Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Кеширование и обновление данных

Кеш — сохранённый результат, который отдают повторно, не выполняя работу заново. Next.js умеет кешировать ответы fetch и готовые страницы. В Next.js 16 есть две модели кеширования: обычная, которая работает в новом проекте сразу, и Cache Components, которую включают настройкой. Этот урок — про обычную модель, о Cache Components рассказывает отдельный урок.

Важно: в режиме разработки кеша почти нет

npm run dev отрисовывает страницы заново на каждый запрос. Чтобы увидеть, как работает кеш на самом деле, соберите и запустите проект:

npm run build
npm run start

fetch по умолчанию

// app/external/page.tsx (фрагмент)
const response = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=3');

Такой запрос не сохраняется в кеше. Но есть тонкость: если страница не использует ничего, что зависит от запроса посетителя (куки, заголовки, searchParams), Next.js целиком отрисует её при сборке и будет отдавать готовый HTML. Данные внутри тогда тоже «застынут» до следующей сборки. Подробнее — в уроке о статической и динамической отрисовке.

Включить кеш для fetch

НастройкаЧто происходит
cache: 'force-cache'Ответ сохраняется и используется повторно
cache: 'no-store'Запрос выполняется каждый раз
next: { revalidate: 60 }Ответ хранится 60 секунд, потом обновляется
next: { tags: ['posts'] }Ответу даётся метка для ручного сброса
// app/external/page.tsx (фрагмент)
const response = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=3', {
  next: { revalidate: 60, tags: ['posts'] },
});

Первый посетитель получает свежие данные, следующие минуту — сохранённые. Запрос после этой минуты отдаёт старую версию и запускает обновление в фоне.

Время жизни для всей страницы

Вместо настройки каждого запроса можно задать время для страницы, экспортировав переменную revalidate:

// app/posts/page.tsx (фрагмент)
export const revalidate = 60;

Страница /posts будет отрисовываться заново не чаще раза в минуту, даже если данные берутся не через fetch, а из базы.

Сброс кеша после изменений

Когда пользователь добавил статью, ждать минуту не хочется. Для этого в next/cache есть три функции:

ФункцияЧто делаетГде вызывать
revalidatePath('/posts')Помечает страницу устаревшейСерверное действие, обработчик маршрута
updateTag('posts')Сразу удаляет данные с меткой, следующий запрос ждёт свежихТолько серверное действие
revalidateTag('posts', 'max')Помечает данные с меткой устаревшими, обновление в фонеСерверное действие, обработчик маршрута
// app/posts/actions.ts (фрагмент)
import { revalidatePath, updateTag } from 'next/cache';
 
revalidatePath('/posts');
updateTag('posts');

После своей правки пользователь должен сразу видеть результат, поэтому в действиях берут revalidatePath или updateTag. revalidateTag подходит, когда небольшая задержка не страшна, например при обновлении из внешней системы. В Next.js 16 у revalidateTag обязателен второй аргумент — профиль, обычно 'max'; старая форма с одним аргументом устарела.

Кеш в браузере

При переходах через Link браузер помнит макеты, но страницы по умолчанию запрашивает с сервера заново. Исключение — кнопки «Назад» и «Вперёд».

Частая ошибка

Проверять кеширование в npm run dev и делать вывод, что «кеш не работает» или «работает не так». В разработке поведение другое. Проверяйте кеш только после npm run build и npm run start.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.