Вопрос проверяет понимание SSR-пайплайна и разделения ответственности между сервером и браузером.
При SSR HTML формирует сервер, выполняя код приложения на серверной среде. Браузер получает готовый HTML, быстро показывает разметку, а затем загружает JavaScript и “оживляет” страницу, привязывая обработчики и состояние. Это даёт более быструю первую отрисовку и лучшее SEO, но добавляет нагрузку на сервер.
При SSR важно разделять два этапа: “сгенерировать HTML” и “сделать интерфейс интерактивным”.
Определение: SSR (Server-Side Rendering) — подход, при котором HTML страницы генерируется на сервере, а не строится целиком в браузере из JavaScript.
HTML рендерит сервер:
сервер запускает код приложения (например, рендер React-компонентов в строку HTML)
подставляет данные (часто полученные до рендера)
Браузер на этом этапе просто получает HTML и парсит его как обычную страницу.
Браузер сначала отображает страницу “как есть”, но без полноценной интерактивности.
Парсит HTML, строит DOM и отображает контент.
Загружает JS-бандлы приложения.
Выполняет “оживление” (hydration).
Определение: Hydration — процесс, когда клиентский JavaScript “подхватывает” уже отрендеренный HTML, связывает его с компонентами и добавляет обработчики событий.
SSR ускоряет появление контента, но интерактивность появляется после загрузки JS.
До hydration:
элементы видны
обработчики кликов/инпутов могут не работать или работать частично (зависит от фреймворка и режима)
После hydration:
React/Next “сопоставляет” существующий DOM и виртуальное дерево
подключаются события, состояние, эффекты
// Сервер: генерирует HTML из компонентов (условно)
const html = renderToString(<App />); // HTML строка
// Клиент: "оживляет" HTML (условно)
hydrateRoot(document.getElementById('root'), <App />);
Плюсы:
быстрее появляется контент (первая отрисовка)
лучше индексируется (SEO)
Минусы:
больше работы на сервере
сложнее кеширование и диагностика
возможны ошибки несоответствия (mismatch), если сервер и клиент рендерят по-разному
Вывод: HTML при SSR рендерит сервер. Браузер затем делает hydration, чтобы страница стала интерактивной, поэтому SSR обычно даёт выигрыш в “первом показе”, но не отменяет необходимость клиентского JS.