Модель кешування в Next.js змінювалася між версіями, і це найчастіше джерело плутанини на співбесідах.
Що відбувається з fetch зараз:
- запити не кешуються за замовчуванням (так з Next.js 15; у 13-14 було навпаки) - кожен запит до сторінки отримує свіжі дані;
- однакові
fetchв одному рендері мемоізуються - можна запитувати дані в кожному компоненті, якому вони потрібні, і запит піде один раз. Мемоізація діє лише в межах одного запиту до сервера; - для власних функцій доступу до бази таку мемоізацію дає
React.cache.
Cache Components (Next.js 16) - нова модель, що вмикається в конфігурації:
// next.config.ts
const nextConfig = { cacheComponents: true };
Тоді кешування задається директивою 'use cache' - на рівні функції з даними чи цілого компонента:
import { cacheLife, cacheTag } from 'next/cache';
export async function getProducts(category: string) {
'use cache';
cacheLife('hours');
cacheTag('products');
return db.product.findMany({ where: { category } });
}
- аргументи стають частиною ключа кешу - різні категорії кешуються окремо;
cacheLifeзадає тривалість (документація радить додавати її до кожної директиви);cacheTag+revalidateTag('products')- точкове скидання кешу після зміни даних, наприклад у серверній функції після збереження товару;- кешовані частини стають статичною «оболонкою» сторінки, а некешовані - рендеряться під час запиту всередині
<Suspense>і надходять потоком.
Пастки:
- персональні дані в кеші: функція з
'use cache', що читає дані поточного користувача, спільна для всіх, якщо користувач не є частиною ключа. Значення зcookies()/headers()всередині кешованої області використовувати не можна - їх передають аргументами; - застарілі дані після змін - без
revalidateTag/revalidatePathу місці зміни користувачі бачитимуть старе до кінця терміну; - документація для старої моделі (опції
fetch{ next: { revalidate } },export const revalidate) досі трапляється - вона стосується режиму без Cache Components.
Порівняно з Laravel: це аналог Cache::remember з тегами, але вбудований у рендер сторінок.