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: гидратацию.

Проверьте себя
1. В чём ключевое различие между SSR и SPA?
ASSR работает без JavaScript, а SPA — без HTML
BВ SSR готовый HTML собирается на сервере и отдаётся сразу, в SPA HTML собирается в браузере после загрузки JS
CSPA быстрее SSR во всех сценариях
DSSR можно использовать только для статических сайтов
2. Почему SSR важен для SEO?
AПоисковики не умеют читать CSS без сервера
BСервер отдаёт готовый HTML с контентом и мета-тегами, который робот индексирует без исполнения JavaScript
CSSR автоматически поднимает сайт в топ выдачи
DSEO работает только при отключённом JavaScript