0Pricing
React Academy · Lesson

Selective Hydration & Streaming HTML

Use Suspense boundaries to stream HTML chunks and hydrate interactive islands first.

Selective Hydration & Streaming HTML is a free React Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Problem with Full-Page Hydration

Traditional SSR hydrates the entire page at once. If one part of the page has heavy JavaScript (like a map or chart), it blocks hydration of the rest — including simple interactive buttons.

Streaming HTML with renderToPipeableStream

React 18's streaming API sends HTML in chunks. The page shell arrives immediately; Suspense boundaries fill in content as it resolves — users see the UI before all data is ready.

const { pipe } = renderToPipeableStream(<App />, {
  bootstrapScripts: ['/bundle.js'],
  onShellReady() {
    res.setHeader('content-type', 'text/html');
    pipe(res);
  },
  onError(error) {
    console.error(error);
  },
});

How Streaming Works in Practice

React renders components that don't suspend immediately (shell). When a Suspense boundary's data resolves, React sends an HTML chunk to fill it in, plus a script tag to instruct the browser where to put it.

Selective Hydration

With streaming, React 18 can hydrate components independently. If a user clicks an element that hasn't been hydrated yet, React prioritizes hydrating that component first — then continues with the rest.

Suspense Boundaries as Streaming Units

Each <Suspense> boundary is a streaming unit. The fallback is sent immediately; the real content streams in later. Nest Suspense boundaries to stream at the right granularity.

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 Streaming with loading.tsx

In Next.js App Router, loading.tsx is the Suspense fallback. The page shell (layout) streams first; the page content streams when its async function resolves.

// 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} />;
}

Client Components Inside Suspense

Server Components use Suspense for data streaming. Client Components use Suspense for lazy loading. Both benefit from selective hydration.

// Lazy-loaded client component — hydrates selectively
const HeavyChart = lazy(() => import('./HeavyChart'));

function Dashboard() {
  return (
    <Suspense fallback={<ChartSkeleton />}>
      <HeavyChart />
    </Suspense>
  );
}

Priority-Based Hydration

If the user interacts with a not-yet-hydrated component (e.g., a click), React 18 synchronously hydrates that component first, before completing hydration of other parts of the page.

onShellReady vs onAllReady

onShellReady fires when the shell (non-suspended parts) is ready to stream. onAllReady fires when everything is rendered — useful for static generation or when you must send the full HTML at once.

// For streaming (progressive rendering):
onShellReady() { pipe(res); }

// For full HTML (e.g., static export, SEO bots):
onAllReady() { pipe(res); }

Abort Controller

Pass an AbortController signal to cancel SSR for slow renders (e.g., timeout exceeded).

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout

const { pipe } = renderToPipeableStream(<App />, {
  signal: controller.signal,
  onShellReady() { pipe(res); },
});

clearTimeout(timeoutId);

Measuring Streaming Impact

Use Lighthouse or WebPageTest to measure Time To First Byte (TTFB) and Largest Contentful Paint (LCP) before and after enabling streaming to quantify the improvement.

Quick Check

What happens in React 18's selective hydration when a user clicks an element that hasn't been hydrated yet?

Recap

Streaming SSR uses renderToPipeableStream and Suspense boundaries to send HTML progressively. Each Suspense boundary streams independently. Selective hydration prioritizes user-interacted elements. In Next.js, loading.tsx is the automatic Suspense fallback for page-level streaming.

Frequently asked questions

Is the “Selective Hydration & Streaming HTML” lesson free?

Yes — the full text of “Selective Hydration & Streaming HTML” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.

What will I learn in “Selective Hydration & Streaming HTML”?

Use Suspense boundaries to stream HTML chunks and hydrate interactive islands first. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start React Academy?

No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Selective Hydration & Streaming HTML” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this React Academy lesson?

Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. How React SSR Works Under the Hood
  2. Hydration Errors: Causes & Fixes
  3. Selective Hydration & Streaming HTML
  4. Islands Architecture Pattern
← Back to React Academy