Что Next.js предоставляет «из коробки»

  • Кэш данных – В Next.js 13+ каждый вызов fetch() попадает в кэш в памяти на время выполнения запроса. Добавление опции revalidate указывает среде выполнения обновлять данные через определенный интервал, превращая «горячий» вызов API в «холодный» только тогда, когда это действительно необходимо.
  • Кэш всего маршрута – Фреймворк сохраняет отрендеренный HTML и данные, необходимые для всего маршрута. Повторные посетители видят мгновенный переход, так как сервер пропускает этап рендеринга.
  • ISR – Статические страницы перегенерируются в фоновом режиме, пока старая версия продолжает обслуживать трафик. Это позволяет поддерживать большой сайт статичным без полной пересборки при каждом изменении контента.
  • Кэширование в Server Component через cache() – Хелпер cache от React мемоизирует ресурсоемкие вычисления или соединения с базой данных на время одного запроса, предотвращая дублирование работы внутри дерева компонентов страницы.

Эти кэши решают проблему «первого обращения», но все еще живут внутри процесса Node. Чтобы защитить сервер и базу данных, выносите кэширование на более внешние уровни.

Внешние уровни, которые можно добавить

Уровень Что хранит Типичный инструмент Как это помогает
CDN Статические ресурсы, HTML, API JSON Cloudflare, Akamai, AWS CloudFront Перемещает контент на edge-локации, сокращая время отклика (round-trip) для пользователя
Reverse proxy Ответы целых страниц до того, как они достигнут Node Nginx, Varnish Напрямую отдает закэшированные страницы, снижая нагрузку на экземпляр Next.js
Application-level cache Результаты ресурсоемких запросов к БД или вызовов API Redis, Memcached Предоставляет быстрое хранилище «ключ-значение», которое сохраняется после перезапуска сервера и может использоваться несколькими экземплярами приложения

Каждый уровень находится дальше от исходной базы данных, поэтому промах (cache miss) на одном уровне каскадом передается на следующий, и в конечном итоге запрос достигает базы данных только тогда, когда это абсолютно необходимо.

Поддержание актуальности кэша

Инвалидация (сброс кэша) — это то, на чем спотыкаются большинство команд. Хорошо работают три практических паттерна:

  • На основе времени (TTL) – Назначьте фиксированный срок действия записи кэша. Просто настроить, но это может привести к выдаче устаревших данных до истечения таймера.
  • Событийная модель – Подключитесь к вашей CMS или любому источнику данных, который отправляет вебхук при изменении контента. Вебхук инициирует очистку соответствующей записи кэша.
  • На основе тегов – Привяжите логический тег к группе запросов fetch (например, product-list). Когда любой элемент в этой группе меняется, один вызов revalidateTag('product-list') очищает все записи, имеющие этот тег.

Комбинирование этих подходов позволяет найти баланс между актуальностью данных и частотой попаданий в кэш (cache-hit rate).

Иерархия, которая подходит большинству команд

  1. Кэш браузера – Статическим ресурсам (CSS, JS, изображениям) назначается длительный max-age, чтобы устройство пользователя больше не обращалось к сети.
  2. CDN – Edge-узлы кэшируют полные HTML-страницы и API JSON, соблюдая заголовки Cache-Control, которые вы устанавливаете в Next.js.
  3. Reverse proxy – Экземпляр Nginx или Varnish стоит перед сервером Next.js, отдавая закэшированные ответы для редко меняющихся маршрутов.
  4. Внутренний кэш Next.js – Кэши данных и маршрутов фреймворка отвечают за мемоизацию в рамках запроса и ISR.
  5. Кэш приложения – Redis хранит результаты тяжелых запросов к базе данных, используя в качестве ключей параметры запроса или теги.
  6. База данных – Первоисточник истины, к которому обращаются только при промахе кэша на всех вышестоящих уровнях.

Когда поступает запрос, он проходит по этому списку сверху вниз, пока какой-либо