Как работает SSR React изнутри
Проследите путь renderToString/renderToPipeableStream и разберитесь, как клиент подхватывает гидратацию.
«Как работает SSR React изнутри» — бесплатный урок React Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.
Проблема, которую решает SSR
Клиентскому React требуется JavaScript для отрисовки. Пользователи видят пустую страницу, пока JS не загрузится и не выполнится. SSR заранее отрисовывает HTML на сервере, поэтому пользователи сразу видят содержимое, что повышает воспринимаемую производительность и улучшает SEO.
renderToString
Исходный API SSR: renderToString(<App />) синхронно отрисовывает дерево компонентов в строку HTML на сервере.
import { renderToString } from 'react-dom/server';
import App from './App';
// In an Express handler:
app.get('*', (req, res) => {
const html = renderToString(<App />);
res.send(`
<!DOCTYPE html>
<html><body>
<div id="root">${html}</div>
<script src="/bundle.js"></script>
</body></html>
`);
});Гидратация на клиенте
После получения HTML браузер разбирает его и отображает интерфейс. Затем hydrateRoot() React присоединяет обработчики событий и делает статический HTML интерактивным — это гидратация.
// client/index.tsx
import { hydrateRoot } from 'react-dom/client';
import App from './App';
hydrateRoot(document.getElementById('root'), <App />);Что происходит во время гидратации
React одновременно обходит отрисованный сервером DOM и виртуальный DOM. Если они совпадают, React присоединяет обработчики, не изменяя DOM. Если они различаются, он выводит предупреждение о гидратации и исправляет DOM.
renderToPipeableStream
Потоковый API React 18 отправляет HTML фрагментами по мере готовности данных, позволяя браузеру постепенно отображать содержимое, пока сервер продолжает обработку.
import { renderToPipeableStream } from 'react-dom/server';
app.get('*', (req, res) => {
const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/bundle.js'],
onShellReady() {
res.setHeader('content-type', 'text/html');
pipe(res); // starts streaming
},
});
});Suspense и потоковая передача
При потоковом SSR границы Suspense сначала передают резервный вариант, а затем заменяют его содержимым, когда данные становятся доступны, — не блокируя первоначальную отправку HTML.
// The shell (nav, layout) streams immediately;
// <UserProfile> suspends and streams when data resolves
function App() {
return (
<Layout>
<Suspense fallback={<Skeleton />}>
<UserProfile /> {/* streams after data loads */}
</Suspense>
</Layout>
);
}Сериализация данных
Данные, полученные на сервере, должны быть serialized и встроены в HTML, чтобы клиент мог прочитать их во время гидратации без повторного запроса.
// Server:
const data = await fetchData();
const html = renderToString(<App data={data} />);
const serialized = JSON.stringify(data).replace(/</g, '\\u003c');
// Inline data in HTML:
`<script>window.__INITIAL_DATA__ = ${serialized};</script>`
// Client hydration reads:
const data = window.__INITIAL_DATA__;Различия окружений
Код сервера выполняется в Node.js, а не в браузере. Код, обращающийся к window, document или localStorage, завершается с ошибкой на сервере. Используйте проверку typeof window !== 'undefined'.
const isBrowser = typeof window !== 'undefined';
function getTheme() {
if (!isBrowser) return 'light'; // server-safe default
return localStorage.getItem('theme') ?? 'light';
}Серверные компоненты React и SSR
SSR отрисовывает компоненты в HTML при каждом запросе. Серверные компоненты React (RSC) устроены иначе: они никогда не отправляют свой JS клиенту и могут быть асинхронными, но для RSC требуется сборщик, поддерживающий протокол RSC (Next.js и другие).
Преимущества потоковой передачи для производительности
Потоковый SSR улучшает время до первого байта (TTFB) для оболочки страницы и обеспечивает выборочную гидратацию — браузер может гидратировать интерактивные островки до того, как потоковая передача HTML всей страницы завершится.
Проверка знаний
Что делает hydrateRoot() иначе, чем createRoot(), если HTML с сервера уже существует?
Итоги
SSR использует renderToPipeableStream, чтобы отправить HTML до загрузки JS. Клиент вызывает hydrateRoot(), чтобы присоединить обработчики событий к HTML с сервера. Потоковый SSR с Suspense сначала отправляет оболочку, а затем асинхронно заполняет содержимое. Защищайте браузерные API проверкой typeof window !== 'undefined'.
Часто задаваемые вопросы
Урок «Как работает SSR React изнутри» бесплатный?
Да — полный текст урока «Как работает SSR React изнутри» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.
Чему я научусь в уроке «Как работает SSR React изнутри»?
Проследите путь renderToString/renderToPipeableStream и разберитесь, как клиент подхватывает гидратацию. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать React Academy?
Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Как работает SSR React изнутри»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке React Academy?
Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Как работает SSR React изнутри
- Ошибки гидратации: причины и исправления
- Выборочная гидратация и потоковая передача HTML
- Паттерн архитектуры островов