Що таке streaming SSR і як він працює?
Проблема класичного SSR
При звичайному (блокувальному) SSR сервер:
- Збирає всі дані (fetch / БД).
- Рендерить весь React-компонент у рядок (
renderToString). - Лише після цього надсилає готовий HTML користувачу.
Користувач бачить сторінку лише після повного рендерингу - навіть якщо частина контенту могла б відобразитися раніше.
Що робить Streaming SSR
Streaming SSR вирішує цю проблему: замість того щоб чекати завершення всього рендеру, сервер стримить готові частини HTML у міру їхньої готовності.
Принцип роботи:
- Сервер починає рендерити React-компонент.
- Щойно частина дерева (наприклад,
<Header>чи<Skeleton>) готова - сервер одразу надсилає її в потік. - Браузер відмальовує ці фрагменти миттєво.
- Інші шматки приходять поступово (наприклад, коли проміси з даними розв'язуються).
- Після завантаження 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>Користувач бачить:
- Скелет інтерфейсу за мілісекунди,
- Контент довантажується плавно,
- Без "білого екрана очікування".
У зв'язці з 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
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.