SSR против SPA: два мира рендеринга
SPA отдаёт пустой HTML и собирает страницу в браузере; SSR собирает страницу на сервере и отдаёт готовую. Разница видна и поисковику, и пользователю.
Суть: в SPA весь рендеринг происходит в браузере после загрузки JavaScript. В SSR сервер выполняет тот же код заранее и отдаёт готовый HTML. Nuxt по умолчанию делает SSR, но умеет и SPA, и промежуточные режимы.
Чтобы понять Nuxt, надо прочувствовать разницу между двумя подходами к рендерингу. Возьмём классическое SPA (Single Page Application) — например, проект на чистом Vue через Vite. Сервер отдаёт почти пустой index.html с одним тегом <div id="app"></div> и ссылкой на бандл JavaScript. Браузер скачивает бандл, запускает Vue, и только тогда на экране появляется контент. До этого момента пользователь видит белый экран, а поисковый робот — пустую страницу.
SSR (Server-Side Rendering) переворачивает порядок. Сервер сам запускает Vue-приложение, строит HTML с реальным контентом и отдаёт его браузеру. Пользователь видит текст и картинки почти сразу, ещё до того как загрузится JavaScript. Поисковик получает полноценную страницу. Затем в браузере подгружается JS и «оживляет» статичный HTML — навешивает обработчики, включает реактивность.
SPA: рендеринг в браузере браузер -> сервер сервер -> пустой HTML + bundle.js браузер качает JS -> запускает Vue -> рисует контент [белый экран всё это время] SSR: рендеринг на сервере браузер -> сервер сервер запускает Vue -> готовый HTML с контентом сервер -> HTML (виден сразу) + bundle.js браузер -> гидратация -> страница интерактивна
Почему это так важно? Три причины. Первая — скорость первой отрисовки: пользователь видит контент раньше, особенно на медленных сетях и слабых телефонах. Вторая — SEO: поисковые роботы исторически плохо исполняют JavaScript, и пустой HTML SPA может попросту не проиндексироваться. SSR отдаёт готовый текст, который индексируется идеально. Третья — превью в соцсетях: когда вы кидаете ссылку в мессенджер, бот читает мета-теги из HTML; в SPA их там нет.
Как работает под капотом
При SSR Nuxt держит на сервере экземпляр Node.js, который умеет исполнять ваше Vue-приложение в «безголовом» режиме — без браузера. Vue рендерит компоненты в строку HTML. Эта строка вместе со специальным «полезным грузом» (payload) — сериализованным состоянием — отправляется клиенту. В браузере Nuxt не рендерит всё заново, а берёт уже готовый HTML и аккуратно «подключается» к нему. Этот процесс называется гидратацией.
Смоделируем разницу подходов простой функцией: представим «рендер» как сборку строки. В SSR мы собираем её заранее, в SPA — в браузере по событию.
// Грубая модель: что значит "рендерить" на сервере и в браузере.
function renderPage(state) {
// Та же функция, что в SSR выполнится на сервере,
// а в SPA — в браузере. Код один, среда разная.
return "<h1>" + state.title + "</h1><p>Товаров: " + state.count + "</p>";
}
const state = { title: "Каталог", count: 42 };
// SSR: сервер уже отдал это в HTML
const ssrHtml = renderPage(state);
console.log("Сервер отдал готовый HTML:");
console.log(ssrHtml);
// SPA: браузер получил пустоту и строит сам
console.log("\nSPA получил бы сначала: <div id=app></div>");
console.log("а контент появился бы только после запуска JS.");
Попробуй сам ▶ — обе ветки используют одну функцию renderPage. Вся идея SSR в том, что эта функция выполняется заранее на сервере.
Частые ошибки
- Думать, что SSR отменяет JavaScript. Нет: JS всё равно грузится для интерактивности. SSR лишь даёт быстрый первый кадр.
- Использовать SSR там, где он не нужен. Внутренняя админка без SEO может работать как SPA — это снимает нагрузку с сервера.
- Забывать про стоимость сервера. SSR требует живого Node-процесса. Статический сайт (SSG) может быть дешевле, если контент не меняется.
Best practices
- Публичные страницы с контентом (лендинги, блог, каталог) — всегда SSR ради SEO и скорости.
- Приватные интерфейсы без SEO можно перевести в SPA-режим через
routeRulesдля отдельных путей. - Не выбирайте режим «вообще» — Nuxt позволяет смешивать стратегии по маршрутам.
Итог: SSR и SPA — это о том, где собирается HTML. Nuxt по умолчанию выбирает SSR ради скорости и SEO, но оставляет вам гибкость. Следующий шаг — разобрать, что происходит после отдачи HTML: гидратацию.