Учебник веб-разработки
Разделы учебника
На этой странице

VI. HTTP, Next.js и кеширование

Где и когда рендерится страница: CSR, SSR, SSG и ISR

Оглавление · React · Архитектура

Задача: проследить путь от данных до первого содержимого страницы и интерактивного интерфейса. Нужны React и различие браузера и сервера. CSR/SSR/SSG/ISR описывают стратегии; один сайт может сочетать их.

Два независимых вопроса

Первый вопрос — где выполняется код компонента. Второй — когда появляется и обновляется результат маршрута. Server Component не означает автоматически «на каждый HTTP-запрос», а Client Component — «без предварительного HTML». Server и Client Components.

Для модели page = render(data, params) выберем момент вычисления и срок переиспользования результата. Данные могут иметь собственный кеш: даже новый рендер не доказывает, что каждое чтение дошло до CMS.

СтратегияКогда появляется основное содержимоеЧто важно для повторного посещения
CSRВ браузере после выполнения JS и получения нужных данныхЗагрузка кода, API и состояние клиента
SSRСервер вычисляет представление при запросеЗадержка вычислений, источник и его кеш
SSGПредставление подготовлено заранее, обычно при сборкеПовторная выдача готового результата
ISRСтатический результат переиспользуется и обновляется по политикеМомент истечения, инвалидирование и ошибки обновления

Таблица упрощает модель: SSR может отдавать части потоком, CSR может использовать заранее подготовленную оболочку, а SSG — содержать интерактивные блоки. Для понимания страницы важнее путь конкретных данных, чем одна аббревиатура сайта.

Первое открытие

Исходник схемы
sequenceDiagram
  participant Browser as Браузер
  participant Server as Сервер приложения
  participant Data as Источник данных
  alt Основное содержимое через CSR
    Browser->>Server: Запрос оболочки и JS
    Server-->>Browser: Оболочка и код
    Browser->>Data: Запрос данных через доступный API
    Data-->>Browser: Данные
    Browser->>Browser: Вычислить интерфейс
  else Содержимое через SSR
    Browser->>Server: Запрос страницы
    Server->>Data: Прочитать данные или их кеш
    Data-->>Server: Данные
    Server-->>Browser: HTML и ресурсы
  end

Стрелки показывают порядок, не обещают число TCP-соединений. В CSR браузер обращается к разрешённому публичному API, а не получает внутренний CMS-токен. При SSR задержка источника может задерживать HTML; при CSR она может задерживать основное содержимое уже после появления оболочки.

При SSG загрузка данных и рендер вынесены в подготовку:

Исходник схемы
flowchart LR
  CMS["Опубликованные данные"] --> Build["Сборка / подготовка"]
  Build --> Page["Готовая страница"]
  Request["Запрос посетителя"] --> Serve["Выдать готовый результат"]
  Page --> Serve

Стрелки означают этапы подготовки и выдачи. Не каждый запрос повторяет сборку. Если источник изменился после подготовки, сохранённый результат сам об этом не узнает — нужна политика обновления.

Гидратация и Server Components

Гидратация связывает предварительный HTML интерактивного React-дерева с его клиентской логикой. Начальный результат клиента должен согласоваться с серверным: случайность, текущие часы или разные исходные данные могут создать расхождение. hydrateRoot.

В Next App Router Server Components формируют RSC payload. Для первого открытия Next также готовит HTML; клиент использует payload для дерева, а JS Client Components — для интерактивности. При переходе внутри приложения не обязательно загружается полный HTML-документ заново. Путь первого открытия и навигации.

"use client" задаёт границу клиентского модуля и его импортов. Серверный компонент не отправляет своё исполнение в браузер, но может передать результат вложенным интерактивным блокам. При пересечении границы данные должны быть совместимы с сериализацией React; внутренние токены остаются на сервере.

Поэтому граф импортов и дерево интерфейса — разные схемы. Переданный сервером React-узел может оказаться внутри клиентской рамки; это не превращает серверный модуль в клиентский импорт. Интерактивные компоненты по-прежнему нельзя строить на функции CMS-доступа, случайно попавшей в браузерный bundle.

ISR: обновляется результат, а не весь релиз

ISR сохраняет статическую выдачу между обновлениями. Политика может зависеть от времени и от явного инвалидирования. Это механизм приложения с серверным исполнением, а не возможность любого каталога экспортированных HTML. ISR в Next.js.

Для нашей модели различаем три момента: изменение источника, истечение записи кеша и получение нового представления. Они не обязаны совпасть. Сценарий по времени может сначала отдать старый результат и запустить обновление в фоне; немедленное истечение данных через webhook задаёт другой путь следующего чтения. Конкретное поведение Atmanki разобрано в SSG/ISR.

ISR не является push-доставкой интерфейса в уже открытые вкладки. Нужны новое обращение, навигация или отдельно спроектированный механизм уведомления клиента. Публикация записи и успешный ответ webhook не означают, что все посетители уже видят новую страницу.

Streaming и Suspense

Streaming позволяет передавать готовые части ответа, пока другие ещё ожидаются. Suspense задаёт границу ожидания и fallback для поддерживаемой React-работы. Это не новая система хранения и не автоматическая валидация данных. Потоковая выдача Next.js.

Быстрый заголовок и медленный раздел могут быть разделены, чтобы не держать весь интерфейс до готовности последнего. Но отправленная часть ответа уже фиксирует некоторые свойства HTTP-ответа: позднее решение «контент не найден» нельзя оценивать только по видимому тексту. Проверяйте и код ответа, и HTML, и содержимое после загрузки клиентских ресурсов.

Что реализовано в Atmanki

Сайт использует output: "standalone". Layout задаёт revalidate = 3600, CMS-клиент — явный кеш чтений. Детальная новость готовит известные slug через generateStaticParams и допускает генерацию новых адресов. Это SSG с ISR; Next-сервер также обслуживает API и webhook.

Учебник использует output: "export": Markdown/MDX превращаются в файлы при сборке. После изменения текста нужна новая сборка и публикация. Поиск и схемы интерактивны в браузере, но это не ISR экспортированного учебника. У двух приложений разные правила обновления.

Ошибка CMS не равна отсутствию новости. В проекте настоящее отсутствие вызывает notFound; отказ источника остаётся ошибкой. Ограничение первоначального HTML при fallback-404 конкретной версии описано в SSG/ISR. Здесь не утверждается, что нынешняя публикация проверена на живом VPS.

Практика и самопроверка

Изучите конфигурации обоих приложений и нарисуйте два пути изменения: правка Markdown → новая сборка учебника; publish CMS → инвалидирование сайта. Отметьте место, где нужен сервер Next, и место, где достаточно раздачи файлов.

В локальном docs dev-сайте откройте исходный HTML и вкладку Network. Найдите текст главы до работы JS, а затем сравните интерактивный поиск. Измените локальный Markdown: dev-обновление не доказывает способ публикации production.

Для сайта прочитайте существующую проверку: найдите подтверждение готовой страницы, HIT и обновления после webhook. Запуск полной проверки — отдельное локальное упражнение по правилам тестирования, не команда для production CMS.

Объясните, почему «серверный компонент», «динамический маршрут» и «новые данные при каждом посещении» не означают одно и то же.