Режимы рендеринга в Nuxt 3
Nuxt 3 позволяет гибко управлять тем, где и когда рендерится HTML: на сервере при каждом запросе, во время сборки, в браузере или по гибридной схеме. Правильный выбор режима влияет на SEO, время до первого контента, нагрузку на сервер и сложность инфраструктуры.
В этой статье разберём SSR, SSG, CSR, ISR и SWR, настройки ssr, prerender, routeRules, а также механизм гидратации Vue-приложения — ключевой процесс, который связывает серверный HTML с интерактивным клиентским приложением.
Общие концепции методов рендеринга без привязки к фреймворку разобраны в статье Методы рендеринга раздела «Производительность». Здесь — реализация в Nuxt 3:
routeRules,prerender,ssrи гидратация.
Содержание
- Обзор режимов рендеринга
- SSR — Server-Side Rendering
- CSR — Client-Side Rendering
- SSG — Static Site Generation
- ISR — Incremental Static Regeneration
- SWR — stale-while-revalidate
- Гибридный рендеринг через routeRules
- Глобальная настройка через ssr
- Гидратация Vue-приложения
- Как выбрать режим рендеринга
- Лучшие практики и антипаттерны
- Ключевые тезисы для интервью
- Заключение
- Полезные ссылки
Обзор режимов рендеринга
| Режим | Когда рендерится | Где выполняется | Подходит для |
|---|---|---|---|
| SSR | На каждый запрос | Сервер | Динамических сайтов с SEO: маркетплейсы, соцсети, дашборды |
| SSG | Во время сборки | Сборщик | Документация, блоги, лендинги, сайты с редко меняющимся контентом |
| CSR | В браузере | Клиент | Админки, SPA, приложения без требований к SEO |
| ISR | При первом запросе + фоновое обновление | Сервер/сборщик | Блоги, каталоги, страницы с контентом, который обновляется периодически |
| SWR | Кэш на сервере + фоновое обновление | Сервер | Данные, допускающие кратковременное устаревание |
Nuxt 3 позволяет комбинировать эти режимы на уровне отдельных маршрутов через routeRules. Это значит, что главная страница может быть SSG, админка — CSR, а каталог товаров — ISR в рамках одного приложения.
SSR — Server-Side Rendering
По умолчанию Nuxt 3 рендерит HTML на сервере для каждого входящего запроса. Браузер получает готовую страницу, что улучшает SEO, первую отрисовку и поведение в социальных сетях.
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true, // значение по умолчанию
});
Как работает SSR в Nuxt
- Серверный движок Nitro получает запрос.
- Выполняется код Vue-компонентов и composables на сервере.
useFetch/useAsyncDataзагружают данные на сервере.- Vue рендерит HTML-строку.
- HTML отправляется клиенту вместе с данными гидратации.
- В браузере Vue «оживляет» статический HTML, добавляя реактивность и обработчики событий.
Преимущества SSR
- Хороший SEO и индексация поисковиками.
- Быстрая первая отрисовка (FCP).
- Корректные Open Graph и Twitter Card превью.
- Работа даже при отключённом или медленном JavaScript на этапе загрузки.
Недостатки SSR
- Серверная нагрузка растёт с трафиком.
- Нужен сервер или serverless-окружение.
- Опасность утечек памяти и ошибок, связанных с
window/document.
CSR — Client-Side Rendering
При ssr: false Nuxt работает как обычное Vue SPA. Сервер отдаёт минимальный HTML, а рендеринг происходит в браузере.
// nuxt.config.ts
export default defineNuxtConfig({
ssr: false,
});
Когда применять CSR
- Админ-панели и внутренние инструменты.
- Приложения, где SEO не важен.
- Сложные интерактивные интерфейсы с большим количеством клиентского состояния.
Особенности
useFetchиuseAsyncDataвыполняют запросы уже в браузере, после монтирования.- Первая загрузка может быть медленнее, чем у SSR.
- Не требуется серверный рендеринг — можно развернуть на статическом хостинге.
SSG — Static Site Generation
npx nuxi generate
Команда nuxi generate предварительно рендерит все страницы во время сборки и кладёт готовые HTML-файлы в .output/public/. Результат можно разместить на любом статическом хостинге: Netlify, Vercel, GitHub Pages, S3.
Пример
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
'/about': { prerender: true },
},
});
npx nuxi generate
Что попадает в SSG
- Страницы, доступные во время сборки.
- Статические данные, полученные через
useFetch/useAsyncDataпри генерации.
Ограничения SSG
- Динамические маршруты с параметрами нужно перечислить через
nitro.prerender.routesилиgenerate.routes. - Контент обновляется только при новой сборке (если не используется ISR).
- Любые данные, недоступные во время сборки, придётся загружать на клиенте.
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
prerender: {
routes: ['/users/1', '/users/2', '/users/3'],
},
},
});
ISR — Incremental Static Regeneration
ISR кэширует статически сгенерированную страницу на заданное время. При первом запросе страница может генерироваться или браться из кэша; по истечении TTL она обновляется в фоне при следующем запросе.
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/blog/**': { isr: 60 }, // кэш 60 секунд
},
});
Как работает ISR
- Первый посетитель получает страницу из кэша или триггерит генерацию.
- Пока TTL не истёк, отдаётся закэшированная версия.
- После истечения TTL следующий запрос возвращает старую версию и запускает фоновое обновление.
ISR без TTL
export default defineNuxtConfig({
routeRules: {
'/blog/**': { isr: true }, // вечный кэш до ручной инвалидации
},
});
Такой подход похож на SSG, но позволяет генерировать страницы лениво, по запросу.
SWR — stale-while-revalidate
SWR похож на ISR, но работает на уровне серверного ответа: сервер отдаёт закэшированную версию и одновременно обновляет данные в фоне.
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/api/products': { swr: 60 },
'/products/**': { swr: 300 },
},
});
ISR vs SWR
| ISR | SWR | |
|---|---|---|
| Уровень | Страница | Ответ сервера / API |
| Поведение | Статическая генерация + фоновое обновление | Кэш + фоновое обновление |
| Применение | Страницы с редкими обновлениями | API-эндпоинты, динамические страницы |
На практике в Nuxt isr и swr часто дают схожий результат для страниц, но swr более универсален для API.
Гибридный рендеринг через routeRules
routeRules — мощный инструмент для тонкой настройки поведения маршрутов. Правила задаются в nuxt.config.ts и поддерживают glob-пatterns.
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// Главная страница — SSG
'/': { prerender: true },
// Блог — ISR с обновлением каждые 60 секунд
'/blog/**': { isr: 60 },
// Каталог — SWR на 5 минут
'/products/**': { swr: 300 },
// Админка — чистый CSR
'/admin/**': { ssr: false },
// API — CORS-заголовки
'/api/**': { cors: true },
// Редирект
'/old-page': { redirect: '/new-page' },
},
});
Основные опции routeRules
| Опция | Назначение |
|---|---|
ssr: false | Отключить серверный рендеринг для маршрута. |
prerender: true | Предварительно отрендерить страницу при сборке. |
isr: number | true | ISR с указанным TTL или бессрочно. |
swr: number | true | SWR-кэширование ответа. |
redirect: string | Редирект на другой URL. |
cors: boolean | Добавить CORS-заголовки. |
headers: object | Произвольные HTTP-заголовки. |
static: boolean | Сервировать маршрут как статический файл. |
routeRules обрабатываются Nitro, поэтому работают независимо от хостинга, если платформа поддерживает соответствующие пресеты.
Глобальная настройка через ssr
Поле ssr в nuxt.config.ts управляет глобальным поведением:
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true, // SSR по умолчанию
// ssr: false, // полный CSR
});
Приоритет настроек
Более конкретные routeRules переопределяют глобальное значение:
export default defineNuxtConfig({
ssr: true,
routeRules: {
'/admin/**': { ssr: false }, // админка будет CSR, остальное — SSR
},
});
prerender в dev-режиме
prerender: true в routeRules влияет на production-сборку и nuxi generate. В dev-режиме страницы всё равно рендерятся динамически.
Гидратация Vue-приложения
Гидратация (hydration) — это процесс, при котором Vue берёт серверный HTML и добавляет к нему реактивность, обработчики событий и компонентный жизненный цикл. Без гидратации страница оставалась бы статичной, несмотря на SSR.
Как происходит гидратация
- Сервер отдаёт HTML и встроенные данные (
__NUXT__). - Браузер загружает JS-бандл.
- Vue запускает приложение на существующем DOM.
- Vue сравнивает виртуальный DOM с реальным DOM.
- Если деревья совпадают, приложение становится интерактивным без перерисовки.
- Если есть несоответствие, Vue пытается восстановить состояние и может выдать предупреждение или перерендерить узел.
Проблемы гидратации
Несоответствие серверного и клиентского DOM
Частая причина — использование Date.now(), Math.random() или window при SSR:
<script setup>
// Опасно: на сервере и клиенте будет разное значение
const randomId = Math.random().toString(36);
</script>
Решение — оборачивать клиентский код в <ClientOnly> или проверять process.client:
<template>
<ClientOnly>
<RandomWidget />
</ClientOnly>
</template>
if (process.client) {
console.log(window.innerWidth);
}
Hydration mismatch
Vue выдаёт предупреждение в консоли:
[Vue warn]: Hydration node mismatch
Причины:
- Разные данные на сервере и клиенте.
- Невалидный HTML (например,
<div>внутри<p>). - Разный рендер в зависимости от
process.client/process.server.
Как избежать проблем
- Не используйте
window,document,localStorageна сервере. - Инициализируйте случайные значения или даты на клиенте.
- Проверяйте консоль на предупреждения гидратации в dev-режиме.
- Используйте
<ClientOnly>для компонентов, которые не должны рендериться на сервере.
<template>
<div>
<h1>SSR-контент</h1>
<ClientOnly>
<ChartComponent />
<template #fallback>
<p>Загрузка графика...</p>
</template>
</ClientOnly>
</div>
</template>
Полная гидратация vs частичная
Nuxt 3 по умолчанию выполняет полную гидратацию всего приложения. В будущих версиях и экспериментальных режимах возможны оптимизации вроде частичной или прогрессивной гидратации, но на момент написания статьи это не стандартное поведение.
Как выбрать режим рендеринга
Выбирайте SSR, если
- Нужен SEO и индексация поисковиками.
- Контент персонализируется для пользователя.
- Есть социальные превью и Open Graph.
- Серверная инфраструктура доступна.
Выбирайте SSG, если
- Контент меняется редко.
- Важна максимальная скорость раздачи.
- Хостинг статический и дешёвый.
Выбирайте ISR, если
- Контент обновляется, но не мгновенно.
- Хочется сочетать скорость SSG с актуальностью SSR.
Выбирайте CSR, если
- Приложение закрытое или административное.
- SEO не требуется.
- Важна максимальная интерактивность и сложное клиентское состояние.
Лучшие практики и антипаттерны
✅ Делайте
- Используйте
routeRulesдля гибкого управления рендерингом по маршрутам. - Применяйте
prerender: trueдля лендингов, страниц политики и другого статического контента. - Используйте ISR/SWR для страниц с периодически обновляемым контентом.
- Проверяйте консоль на ошибки гидратации в dev-режиме.
- Оборачивайте клиентские библиотеки в
<ClientOnly>илиprocess.client. - Тестируйте production-сборку через
nuxi preview, а не только dev-сервер.
❌ Не делайте
- Не отключайте SSR глобально из-за одной страницы — лучше
routeRules. - Не используйте
window/documentв коде, который выполняется на сервере. - Не игнорируйте hydration mismatch — они приводят к лишнему ререндеру.
- Не смешивайте режимы без понимания: CSR-страница не получит SEO-преимуществ SSR.
- Не забывайте, что
nuxi generateиprerenderне подходят для данных, меняющихся на каждый запрос.
Ключевые тезисы для интервью
- Nuxt 3 поддерживает SSR, SSG, CSR, ISR и SWR, которые можно комбинировать через
routeRules. - SSR по умолчанию — HTML рендерится на сервере для каждого запроса, что даёт SEO и быструю первую отрисовку.
- CSR (
ssr: false) превращает Nuxt в обычное Vue SPA; рендеринг происходит в браузере. - SSG (
nuxi generate) создаёт статические HTML-файлы во время сборки. - ISR кэширует статические страницы и обновляет их в фоне по истечении TTL.
- SWR кэширует серверный ответ и обновляет его в фоне.
routeRulesпозволяют задавать разные стратегии для разных маршрутов:prerender,isr,swr,ssr: false,redirect,cors.- Гидратация связывает серверный HTML с клиентским Vue-приложением; несоответствие DOM вызывает hydration mismatch.
- Для клиентского кода, несовместимого с сервером, используйте
<ClientOnly>или проверкуprocess.client.
Заключение
Понимание режимов рендеринга — основа для построения производительных и SEO-оптимизированных приложений на Nuxt 3. SSR подходит для динамического контента, SSG — для статики, ISR и SWR — для компромисса между скоростью и актуальностью, а CSR — для закрытых инструментов.
routeRules дают возможность гибко настраивать поведение без разделения проекта на несколько приложений. При этом важно следить за гидратацией: серверный HTML и клиентский Vue должны видеть одно и то же дерево DOM, иначе приложение теряет часть преимуществ SSR.
Следующие статьи раздела продолжат погружение: composables и auto-imports, жизненный цикл приложения, серверная часть Nitro, data fetching, состояние и SEO.
Полезные ссылки
- Nuxt 3 Rendering — официальная документация по режимам рендеринга
- Nuxt routeRules — настройка правил для маршрутов
- Nuxt Nitro — документация серверного движка
- Vue 3 SSR — руководство по SSR в Vue
- Nuxt Hydration — гидратация и клиентский рендеринг