Skip to main content

Що таке streaming SSR і як він працює?

Проблема класичного SSR

При звичайному (блокувальному) SSR сервер:

  1. Збирає всі дані (fetch / БД).
  2. Рендерить весь React-компонент у рядок (renderToString).
  3. Лише після цього надсилає готовий HTML користувачу.

Користувач бачить сторінку лише після повного рендерингу - навіть якщо частина контенту могла б відобразитися раніше.


Що робить Streaming SSR

Streaming SSR вирішує цю проблему: замість того щоб чекати завершення всього рендеру, сервер стримить готові частини HTML у міру їхньої готовності.

Принцип роботи:

  1. Сервер починає рендерити React-компонент.
  2. Щойно частина дерева (наприклад, <Header> чи <Skeleton>) готова - сервер одразу надсилає її в потік.
  3. Браузер відмальовує ці фрагменти миттєво.
  4. Інші шматки приходять поступово (наприклад, коли проміси з даними розв'язуються).
  5. Після завантаження JS виконується hydration - сторінка стає інтерактивною.

Приклад на React 18

Сервер

javascript
import { renderToPipeableStream } from "react-dom/server"; import express from "express"; import App from "./App"; const app = express(); app.get("/", (req, res) => { let didError = false; const stream = renderToPipeableStream(<App />, { onShellReady() { res.status(didError ? 500 : 200); res.setHeader("Content-Type", "text/html"); stream.pipe(res); // HTML починає текти }, onError(err) { didError = true; console.error(err); }, }); });

Клієнт

javascript
import { hydrateRoot } from "react-dom/client"; hydrateRoot(document.getElementById("root"), <App />);

renderToPipeableStream() - потокова версія renderToString(), яка дозволяє React віддавати HTML шматками у міру готовності.


Переваги Streaming SSR

ПеревагаОпис
Миттєвий First PaintПерша частина HTML (шапка, скелетон) видна одразу
Менший TTFB / LCPСервер не чекає кінця рендеру, щоб почати відповідь
Плавне завантаження данихМожна віддавати секції, щойно їхні дані готові
Підтримка SuspenseКомпоненти з React.Suspense автоматично стримляться пізніше
Edge-рендерингПотік чудово працює на CDN / edge-сервері

Як це виглядає в браузері

javascript
[Сервер починає рендерити App] ↓ Надсилає <html><head>...</head><body> ↓ Надсилає <Header> (готовий миттєво) ↓ Поки чекає API → шле <Skeleton /> ↓ Коли дані приходять → підмінює <Skeleton> на <Content /> ↓ Завершує потік </body></html>

Користувач бачить:

  1. Скелет інтерфейсу за мілісекунди,
  2. Контент довантажується плавно,
  3. Без "білого екрана очікування".

У зв'язці з React Suspense

Streaming SSR розкриває весь потенціал Suspense:

javascript
<Suspense fallback={<Loading />}> <Comments /> </Suspense>
  • <Loading /> рендериться і стримиться одразу,
  • <Comments /> додається пізніше, коли дані завантажені, причому React коректно вставить його на місце без перемальовування всієї сторінки.

Де використовується Streaming SSR

  • Next.js 13+ (App Router) - використовується типово.
  • Remix, Astro, Qwik, SvelteKit - теж впроваджують потоковий SSR.
  • Підтримується на Node.js, Deno, Edge (Cloudflare, Vercel).

Потенційні складнощі

ПроблемаОпис
КешуванняПотокові відповіді не можна просто закешувати як готовий HTML
Помилки посеред потокуСкладніше відкотити вже надісланий HTML
Складність налагодженняВажче зрозуміти, на якому етапі щось пішло не так
ІнфраструктураПотрібні сервери, що підтримують streaming (HTTP chunked encoding)

Підсумок

Streaming SSR = "SSR нового покоління":

  • Віддає HTML поступово, без очікування кінця рендеру;
  • Дозволяє користувачу побачити контент раніше;
  • Чудово працює з React 18 + Suspense;
  • Але потребує продуманого керування потоками, кешем і помилками.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.