Методы рендеринга: CSR, SSR, SSG, ISR, SWR и Streaming
Метод рендеринга определяет, где и когда HTML-страница попадает в браузер: строится на клиенте из JavaScript, генерируется на сервере при каждом запросе или создаётся один раз при сборке проекта. От этого выбора зависят четыре ключевых параметра: SEO, скорость первой загрузки (FCP, LCP), актуальность данных и нагрузка на сервер.
Концепции из этой статьи универсальны и одинаково применимы к Next.js, Nuxt и другим full-stack фреймворкам. Фреймворк-специфичная реализация разобрана отдельно: Методы рендеринга в Next.js и Режимы рендеринга в Nuxt 3.
Содержание
- Что такое метод рендеринга
- CSR — Client-Side Rendering
- SSR — Server-Side Rendering
- SSG — Static Site Generation
- ISR — Incremental Static Regeneration
- SWR — stale-while-revalidate
- Streaming SSR
- Гидратация
- CDN — Content Delivery Network
- HTTP-кэширование
- Edge Functions и Serverless
- Сравнительная таблица
- Как выбрать метод рендеринга
- Методы рендеринга во фреймворках
- Ключевые тезисы для интервью
- Заключение
- Сноски
- Полезные ссылки
Что такое метод рендеринга
Рендеринг — это процесс превращения кода приложения в HTML, который получает браузер. Главный вопрос метода рендеринга: где выполняется этот процесс.
┌──────────────────────────────┬──────────────────────────────┬──────────────────────────────┐
│ CSR │ SSR │ SSG │
│ HTML строится в браузере │ HTML генерируется на сервере│ HTML создаётся при сборке │
│ из JavaScript │ при каждом запросе │ и раздаётся как файл │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│ SEO: плохо │ SEO: отлично │ SEO: отлично │
│ Скорость: медленный FCP │ Скорость: хороший FCP │ Скорость: максимальная │
│ Актуальность: всегда │ Актуальность: всегда │ Актуальность: при сборке │
│ Нагрузка: нет │ Нагрузка: при каждом запросе│ Нагрузка: минимальная │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
Между этими крайними точками есть компромиссные стратегии: ISR и SWR (статическая раздача + периодическое обновление), Streaming (частями вместо целой страницы). Выбор определяется приоритетами проекта: для блога важнее скорость, для дашборда — актуальность, для интернет-магазина — и то и другое.
1. CSR — Client-Side Rendering (Рендеринг на клиенте)
Что это: Страница рендерится полностью в браузере с помощью JavaScript. Сервер отдаёт минимальный HTML и бандл, а контент появляется после выполнения JS.
Как работает:
- Браузер загружает пустой HTML и JavaScript.
- JavaScript выполняется и строит DOM.
- Пользователь видит контент.
Когда использовать:
- Дашборды, приватные страницы, админки
- Интерактивные приложения без SEO-требований
- Контент, не требующий индексации
Плюсы:
- Мгновенная навигация после первой загрузки (SPA-поведение)
- Снижает нагрузку на сервер
- Простая инфраструктура — можно хостить как статику
Минусы:
- Плохо для SEO (поисковики видят пустую страницу)
- Долгая первая загрузка (FCP, LCP) — нужно скачать и выполнить весь JS
- Зависимость от JavaScript: без JS страница не работает
2. SSR — Server-Side Rendering (Рендеринг на сервере)
Что это: Страница генерируется на сервере при каждом запросе. Браузер получает готовый HTML, который затем «оживляется» клиентским JavaScript.
Как работает:
- Сервер получает запрос.
- Выполняется код приложения на сервере, данные подгружаются.
- Сервер формирует HTML-строку и отправляет её.
- Браузер показывает HTML, затем гидратирует страницу — делает её интерактивной.
Когда использовать:
- Динамический контент, который часто меняется (новости, ленты)
- Персонализированные страницы
- Данные, которые должны быть актуальными при каждом запросе
Плюсы:
- SEO-friendly (полный HTML при первом запросе)
- Всегда актуальные данные
- Быстрая первая отрисовка
Минусы:
- Нагрузка на сервер при каждом запросе
- Медленнее, чем статические страницы
- Требует серверной инфраструктуры (Node.js или serverless)
3. SSG — Static Site Generation (Статическая генерация)
Что это: Страницы генерируются один раз при сборке проекта и раздаются как статические файлы (обычно через CDN).
Как работает:
- При сборке выполняется код приложения, данные подгружаются.
- Готовые HTML-файлы сохраняются на диск.
- При запросе браузер мгновенно получает готовый файл.
Когда использовать:
- Блоги, документация
- Маркетинговые страницы
- Контент, который редко меняется
Плюсы:
- Максимальная производительность (HTML кэшируется на CDN)
- Отличное SEO
- Низкая нагрузка на сервер, дешёвый хостинг
Минусы:
- Долгая сборка при большом количестве страниц
- Контент устаревает до следующей сборки
4. ISR — Incremental Static Regeneration (Инкрементальная статическая регенерация)
Что это: Комбинация SSG и SSR. Страницы генерируются статически, но могут обновляться в фоне с заданной периодичностью (TTL) или по событию — без полной пересборки сайта.
Как работает:
- Страница сгенерирована статически и лежит в кэше.
- Пока TTL не истёк, отдаётся закэшированная версия.
- По истечении TTL следующий запрос возвращает старую версию и запускает фоновую регенерацию.
- Следующие запросы получают свежую версию.
Когда использовать:
- Контент, который обновляется периодически (раз в минуту/час/день)
- Большие сайты, где полная пересборка нецелесообразна
- E-commerce (цены, наличие товаров)
Поведение stale-while-revalidate:
- Запрос к странице с невалидным кэшем → stale-while-revalidate.
- Пользователь получает старую версию (мгновенно).
- В фоне генерируется новая версия.
- Следующие запросы получают свежую версию.
Это означает, что первый пользователь после ревалидации может увидеть устаревший контент, но последующие — уже актуальный.
On-Demand Revalidation (по запросу): многие фреймворки поддерживают принудительную инвалидацию кэша по событию (например, при публикации статьи в CMS). Событие вызывает API-эндпоинт, который очищает кэш для конкретной страницы или всех страниц с определённым тегом, и следующий запрос генерирует свежую версию. В Next.js это revalidatePath / revalidateTag, в Nuxt — инвалидация через Nitro.
Плюсы:
- Производительность SSG + актуальность SSR
- Не нужна полная пересборка
- Гибкость в выборе частоты обновления
Минусы:
- Пользователь может увидеть устаревший контент (до ревалидации)
- Сложнее в настройке, чем чистый SSG
- Требует платформы с поддержкой фоновых задач и кэширования
5. SWR — stale-while-revalidate
Что это: Стратегия кэширования на уровне серверного ответа: сервер отдаёт закэшированную версию и одновременно обновляет данные в фоне.
ISR vs SWR:
| ISR | SWR | |
|---|---|---|
| Уровень | Страница | Ответ сервера / API |
| Поведение | Статическая генерация + фоновое обновление | Кэш + фоновое обновление |
| Применение | Страницы с редкими обновлениями | API-эндпоинты, динамические страницы |
На практике для страниц ISR и SWR часто дают схожий результат, но SWR более универсален для API и серверных ответов. Этот же принцип лёг в основу HTTP-директивы stale-while-revalidate (см. HTTP-кэширование).
6. Streaming SSR (Потоковый серверный рендеринг)
Что это: Разновидность SSR, где HTML отправляется частями (чанками) по мере готовности. Вместо ожидания всей страницы сервер отдаёт то, что уже готово, а медленные части подгружаются позже.
Как работает:
- Страница делится на фрагменты (обычно через
Suspense). - Быстрые фрагменты отправляются сразу, тяжёлые — по мере готовности.
- Браузер показывает контент постепенно, не дожидаясь самого медленного запроса.
Когда использовать:
- Страницы с тяжёлыми компонентами
- Когда нужно показать контент как можно быстрее
- Graceful degradation — медленная часть не блокирует остальную страницу
Плюсы:
- Быстрый Time to First Byte (TTFB)
- Прогрессивная загрузка контента
- Лучший пользовательский опыт на медленных страницах
Минусы:
- Сложнее в отладке
- Требует поддержки Suspense/streaming на клиенте
7. Гидратация
SSR и SSG возвращают статический HTML — его видно сразу, но он не интерактивен. Гидратация — это процесс, при котором клиентский JavaScript берёт серверный HTML и добавляет к нему реактивность, обработчики событий и состояние приложения.
Проблемы гидратации:
- Hydration mismatch — сервер и клиент отрендерили разное дерево DOM (например, из-за
Date.now(),Math.random()или доступа кwindow). Приложение теряет часть преимуществ SSR. - Цена гидратации — клиент всё равно должен скачать и выполнить JS, поэтому «лёгкий» серверный HTML не отменяет вес бандла.
Подробнее — в отдельной статье Гидратация.
CDN — Content Delivery Network
Что это
CDN (Content Delivery Network) — сеть серверов, размещённых по всему миру, которая отдаёт контент с ближайшей к пользователю точки. Вместо того чтобы запрашивать HTML из дата-центра в США, пользователь из Москвы получает его из Москвы или Франкфурта.
┌─────────────┐ ┌─────────────────────────────────────────┐
│ Пользователь│ │ CDN │
│ из Москвы │ ──────► │ Москва ──► Франкфурт ──► Лондон ──► │
│ │ │ origin-сервер (если нет в кэше) │
└─────────────┘ └─────────────────────────────────────────┘
▲
│
┌─────────────┐
│ Origin │
│ (основной │
│ сервер) │
└─────────────┘
Что кэширует CDN
- Статические файлы: JS, CSS, шрифты, изображения.
- Сгенерированные HTML-страницы (SSG, ISR, SSR с подходящими заголовками).
- API-ответы — если правильно настроены заголовки.
Преимущества
- Низкая задержка — контент ближе к пользователю.
- Разгрузка origin-сервера — повторные запросы не доходят до него.
- Высокая доступность — CDN выдерживает пиковые нагрузки.
- Защита от DDoS — многие CDN фильтруют вредоносный трафик.
Популярные CDN
- Cloudflare
- Fastly
- AWS CloudFront
- Vercel Edge Network
- KeyCDN
HTTP-кэширование
CDN и браузер кэшируют ответы только тогда, когда это разрешают HTTP-заголовки. Ключевой из них — Cache-Control.
Cache-Control
Cache-Control: public, max-age=0, must-revalidate
Значения директив:
| Директива | Значение |
|---|---|
public | Можно кэшировать и в браузере, и на CDN |
private | Кэшировать только в браузере |
no-store | Не кэшировать вообще |
no-cache | Кэшировать, но каждый раз ревалидировать у origin |
max-age | Сколько секунд ответ считается свежим в браузере |
s-maxage | Сколько секунд ответ считается свежим на CDN |
must-revalidate | После истечения срока обязательно проверять свежесть |
stale-while-revalidate | Можно отдавать устаревший ответ, фоново обновляя |
Ключевая разница: max-age управляет кэшем браузера, s-maxage — кэшем CDN. s-maxage позволяет хранить страницу на CDN дольше, чем в браузере конкретного пользователя.
Примеры
Статические ассеты с длинным кэшем:
Cache-Control: public, max-age=31536000, immutable
immutable говорит браузеру никогда не перепроверять файл — применяется для ресурсов с хэшем в имени (например, app.a1b2c3.js).
ISR-страница:
Cache-Control: public, max-age=0, s-maxage=60, stale-while-revalidate
Персонализированная страница:
Cache-Control: private, no-store
ETag и Last-Modified
Для условных запросов сервер может вернуть:
ETag— хэш содержимого.Last-Modified— время последнего изменения.
Браузер при повторном запросе отправляет If-None-Match или If-Modified-Since. Если ресурс не изменился, сервер отвечает 304 Not Modified без тела ответа — это экономит трафик.
Edge Functions и Serverless
Кроме вопроса «где генерируется HTML», есть вопрос «где выполняется серверный код». Два подхода:
| Характеристика | Edge Functions | Serverless Functions |
|---|---|---|
| Расположение | CDN-узлы по миру | Один или несколько регионов |
| Холодный старт | ~0-5 мс | ~100-500 мс |
| Runtime | V8 Isolate (ограниченный) | Node.js (полный) |
| API | Web API | Node.js API |
Edge Functions подходят для middleware-задач: аутентификация, геолокация, редиректы, A/B-тесты, персонализация. Не подходят для тяжёлых вычислений, работы с файловой системой и больших зависимостей.
Serverless — универсальный выбор для рендеринга страниц и API, где не критична задержка холодного старта. Конкретные реализации различаются по фреймворкам и платформам (подробнее — Edge Runtime в Next.js).
Сравнительная таблица
| Метод | SEO | Скорость | Актуальность | Сложность |
|---|---|---|---|---|
| CSR | Плохо | Медленная FCP | Всегда | Низкая |
| SSR | Отлично | Быстрая | Всегда | Средняя |
| SSG | Отлично | Максимальная | При сборке | Низкая |
| ISR | Отлично | Максимальная | Периодически | Средняя |
| SWR | Отлично | Высокая | Периодически | Средняя |
| Streaming | Отлично | Быстрая TTFB | Всегда | Высокая |
Как выбрать метод рендеринга
Дерево решений:
Нужен ли SEO и индексация?
├── Нет → CSR (дашборды, админки, приватные страницы)
└── Да → Контент меняется часто (каждую секунду/минуту)?
├── Да → SSR
└── Нет → Контент меняется периодически (раз в час/день)?
├── Да → ISR или SWR
└── Нет → SSG
| Сценарий | Рекомендуемая стратегия |
|---|---|
| Блог, документация, лендинг | SSG |
| Маркетинговый сайт с редкими обновлениями | SSG |
| E-commerce | ISR + кэширование или SSR |
| Новостной сайт | ISR или SSR |
| Личный кабинет, дашборд | CSR |
| Персонализированные страницы | SSR |
| Глобальное приложение с низкой задержкой | SSG + CDN + Edge Functions |
| Админка внутри компании | CSR |
| API с допуском к устареванию данных | SWR |
Для большинства проектов оптимален гибридный подход: SSG/ISR для публичных страниц, CSR для интерактивных разделов, CDN — для раздачи статики, Edge — для middleware.
Методы рендеринга во фреймворках
Общие концепции из этой статьи в каждом фреймворке получают свою реализацию и терминологию:
- Next.js — App Router, RSC, Static Export, PPR,
revalidatePath/revalidateTag, Route Segment Config. Разбор: Методы рендеринга в Next.js. - Nuxt 3 —
ssr,nuxi generate,routeRules(prerender,isr,swr,ssr: false), Nitro, гидратация Vue. Разбор: Режимы рендеринга в Nuxt 3.
Ключевые тезисы для интервью
- CSR рендерит страницу в браузере (плохо для SEO, быстрая навигация после загрузки); SSR генерирует HTML на каждый запрос (SEO-friendly, нагрузка на сервер); SSG генерирует HTML при сборке (максимальная производительность, данные устаревают).
- ISR = SSG + периодическое обновление через stale-while-revalidate: первый пользователь после истечения кэша видит старую версию, пока страница регенерируется в фоне.
- SWR работает на уровне серверного ответа и универсален для API; ISR — на уровне страницы.
- Streaming SSR отправляет HTML чанками через Suspense, улучшая TTFB на страницах с тяжёлыми компонентами.
- Гидратация добавляет интерактивность к серверному HTML; hydration mismatch возникает, когда сервер и клиент рендерят разное DOM-дерево.
- CDN кэширует не только JS/CSS/изображения, но и HTML-страницы, снижая нагрузку на origin-сервер.
s-maxageуправляет кэшированием на CDN,max-age— в браузере;stale-while-revalidateпозволяет отдавать устаревший ответ, фоново обновляя его.immutableв Cache-Control говорит браузеру никогда не перепроверять файл — применяется для ресурсов с хэшем в имени.- Edge Functions выполняются на CDN-узлах (~0–5 мс холодный старт) в ограниченном V8 Isolate; подходят для middleware, не для тяжёлой логики.
- Для большинства проектов оптимален гибридный подход: SSG/ISR для публичных страниц, CSR для интерактивных разделов.
Заключение
Метод рендеринга — одно из ключевых архитектурных решений веб-приложения. SSG даёт максимальную производительность для контента, не требующего актуальности. ISR добавляет периодическое обновление без полной пересборки. SSR гарантирует свежие данные при каждом запросе. SWR кэширует ответы с допуском к устареванию. Streaming улучшает TTFB на тяжёлых страницах. CDN и Edge добавляют ещё один слой: кэширование и логика ближе к пользователю.
Эти концепции одинаково работают в Next.js и Nuxt — различается только реализация, поэтому дальше стоит изучить фреймворк-специфичные статьи: Next.js и Nuxt 3.
Сноски
FCP (First Contentful Paint) — время до первого отображения любого контента на экране (текст, изображение, SVG). Показывает, насколько быстро пользователь видит, что страница «загружается».
LCP (Largest Contentful Paint) — время до отрисовки самого крупного видимого элемента (обычно главное изображение или заголовок). Ключевая метрика воспринимаемой скорости загрузки.
Подробнее про метрики — в статье Метрики производительности.