Выборочная гидратация и потоковая передача HTML
Используйте границы Suspense для потоковой передачи фрагментов HTML и сначала гидратируйте интерактивные острова.
«Выборочная гидратация и потоковая передача HTML» — бесплатный урок React Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.
Проблема гидратации всей страницы
Традиционный SSR гидратирует всю страницу сразу. Если одна часть страницы содержит много JavaScript (например, карту или график), она блокирует гидратацию остальной части, включая простые интерактивные кнопки.
Потоковая передача HTML с помощью renderToPipeableStream
Потоковый API React 18 отправляет HTML фрагментами. Оболочка страницы приходит сразу, а границы Suspense заполняются по мере готовности содержимого — пользователи видят интерфейс ещё до загрузки всех данных.
const { pipe } = renderToPipeableStream(<App />, {
bootstrapScripts: ['/bundle.js'],
onShellReady() {
res.setHeader('content-type', 'text/html');
pipe(res);
},
onError(error) {
console.error(error);
},
});Как потоковая передача работает на практике
React сразу отрисовывает компоненты, которые не приостанавливают отрисовку (оболочку). Когда данные границы Suspense становятся доступны, React отправляет HTML-фрагмент для её заполнения, а также тег скрипта, указывающий браузеру, куда его поместить.
Выборочная гидратация
При потоковой передаче React 18 может гидратировать компоненты независимо. Если пользователь нажимает элемент, который ещё не был гидратирован, React в первую очередь гидратирует этот компонент, а затем продолжает работу с остальными.
Границы Suspense как единицы потоковой передачи
Каждая граница Suspense является единицей потоковой передачи. Резервный вариант отправляется немедленно, а настоящее содержимое передаётся позже. Вкладывайте границы Suspense, чтобы передавать содержимое с нужной степенью детализации.
function App() {
return (
<Layout>
{/* Streams first — no data needed */}
<Header />
<Suspense fallback={<ArticleSkeleton />}>
{/* Streams when article data resolves */}
<Article />
</Suspense>
<Suspense fallback={<CommentsSkeleton />}>
{/* Streams independently from Article */}
<Comments />
</Suspense>
</Layout>
);
}Потоковая передача в Next.js с loading.tsx
В маршрутизаторе приложения Next.js файл loading.tsx является резервным вариантом Suspense. Оболочка страницы (макет) передаётся первой, а содержимое страницы — после завершения асинхронной функции.
// app/blog/loading.tsx — shown while page.tsx data loads
export default function Loading() {
return <ArticleSkeleton />;
}
// app/blog/page.tsx — fetches data, streams when ready
export default async function BlogPage() {
const posts = await fetchPosts(); // data fetch happens server-side
return <PostList posts={posts} />;
}Клиентские компоненты внутри Suspense
Серверные компоненты используют Suspense для потоковой передачи данных. Клиентские компоненты используют Suspense для ленивой загрузки. Оба типа получают преимущества от выборочной гидратации.
// Lazy-loaded client component — hydrates selectively
const HeavyChart = lazy(() => import('./HeavyChart'));
function Dashboard() {
return (
<Suspense fallback={<ChartSkeleton />}>
<HeavyChart />
</Suspense>
);
}Гидратация на основе приоритета
Если пользователь взаимодействует с ещё не гидратированным компонентом (например, нажимает кнопку), React 18 синхронно гидратирует этот компонент первым, до завершения гидратации остальных частей страницы.
onShellReady и onAllReady
onShellReady срабатывает, когда оболочка (части, не приостановленные Suspense) готова к потоковой передаче. onAllReady срабатывает, когда отрисовано всё содержимое — это полезно для статической генерации или когда необходимо отправить весь HTML сразу.
// For streaming (progressive rendering):
onShellReady() { pipe(res); }
// For full HTML (e.g., static export, SEO bots):
onAllReady() { pipe(res); }AbortController
Передайте сигнал AbortController, чтобы отменить SSR для медленной отрисовки (например, если превышено время ожидания).
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
const { pipe } = renderToPipeableStream(<App />, {
signal: controller.signal,
onShellReady() { pipe(res); },
});
clearTimeout(timeoutId);Измерение влияния потоковой передачи
Используйте Lighthouse или WebPageTest, чтобы до и после включения потоковой передачи измерить время до получения первого байта (TTFB) и отрисовку самого крупного элемента содержимого (LCP), а затем количественно оценить улучшение.
Быстрая проверка
Что происходит при выборочной гидратации в React 18, когда пользователь нажимает на элемент, который ещё не был гидратирован?
Итоги
Потоковый SSR использует renderToPipeableStream и границы Suspense для постепенной отправки HTML. Каждая граница Suspense передаёт содержимое независимо. Выборочная гидратация отдаёт приоритет элементам, с которыми взаимодействовал пользователь. В Next.js loading.tsx является автоматическим резервным вариантом Suspense для потоковой передачи страницы.
Часто задаваемые вопросы
Урок «Выборочная гидратация и потоковая передача HTML» бесплатный?
Да — полный текст урока «Выборочная гидратация и потоковая передача HTML» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.
Чему я научусь в уроке «Выборочная гидратация и потоковая передача HTML»?
Используйте границы Suspense для потоковой передачи фрагментов HTML и сначала гидратируйте интерактивные острова. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать React Academy?
Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Выборочная гидратация и потоковая передача HTML»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке React Academy?
Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Как работает SSR React изнутри
- Ошибки гидратации: причины и исправления
- Выборочная гидратация и потоковая передача HTML
- Паттерн архитектуры островов