React Streaming

Прогресивне завантаження з межами Suspense, яке передає контент у міру його доступності. Ідеально для Дашбордів, додатків у реальному часі та Прогресивних додатків, де користувачі отримують користь від перегляду контенту інкрементально.

Сервер

🌐
Request
Streaming
🖥️
Сервер отримує запит
Сервер починає рендеринг
Сервер рендерить швидкий контент
Сервер передає chunk HTML 1
<Suspense>
Сервер рендерить повільний контент (Suspense)
Сервер передає chunk HTML 2

Клієнт

Клієнт отримує та відображає chunk 1
Клієнт отримує та відображає chunk 2
React.hydrateRoot()
Сторінка інтерактивна
Переваги x Компроміси

Benefits

  • Прогресивне Завантаження: Швидкий контент з'являється миттєво
  • Кращий UX: Користувачі бачать контент коли він стає доступним
  • Паралельне Завантаження: Множинні компоненти завантажуються незалежно
  • Межі Помилок: Ізольована обробка помилок на компонент

Trade-offs

  • Інкрементальний UI: Макет може змінюватися під час завантаження контенту
  • Потрібен Fallback UX: Потрібно проектувати стани завантаження
  • Складність: Керування множинними межами Suspense
  • Розгляди SEO: Деякий контент завантажується після початкового рендеру
Як реалізувати?

Streaming використовує межі Suspense з Server Components асинхронними. Не можна використовувати хуки в межах Suspense.

import { Suspense } from "react";

export default async function StreamingPage() {
  return (
    <div>
      <Suspense fallback={<div>Завантаження...</div>}>
        <AsyncComponent />
      </Suspense>
    </div>
  );
}

async function AsyncComponent() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();
  return <div>{data.message}</div>;
}
  • Компоненти є асинхронними функціями (без директиви 'use client')
  • Не можна використовувати React hooks (включно з use hook) у Server Components
  • Обгорніть асинхронні компоненти Suspense та надайте fallback
  • Використовуйте loading.js для станів завантаження на рівні маршруту
  • Контент передається клієнту коли стає доступним