InterviewHubPRO
Section Overview
Q324

Question 324 of 445

Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)

73%
React & Modern Frontend (445 Qs)•Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)

What is Streaming SSR and how does React 18+ improve it?

Streaming SSR sends HTML to the browser in chunks as it's generated, rather than waiting for the entire page. React 18+ dramatically improves this with Suspense integration.

Traditional SSR (Pre-React 18)

sql
Server: Wait for ALL data → Generate ALL HTML → Send to client
Client: Receive HTML → Download ALL JS → Hydrate ALL components
Problem: Slow components block entire page!

Streaming SSR (React 18+)

vbnet
Server: Send HTML as it's ready, wrap slow parts in <Suspense>
Client: Render immediately, hydrate progressively
Benefit: User sees content faster!

Basic Example

jsx
import { Suspense } from 'react';

export default function Page() {
return (
  <html>
    <body>
      {/* Sent immediately */}
      <header>
        <h1>My App</h1>
      </header>

      {/* Sent immediately with fallback */}
      <Suspense fallback={<div>Loading comments...</div>}>
        <Comments /> {/* Streamed when ready */}
      </Suspense>

      {/* Also streamed separately */}
      <Suspense fallback={<div>Loading recommendations...</div>}>
        <Recommendations /> {/* Streamed when ready */}
      </Suspense>

      <footer>© 2026</footer>
    </body>
  </html>
);
}

Server Component with Data Fetching

jsx
// This is a Server Component (async!)
async function Comments() {
const comments = await db.comments.findMany();

return (
  <ul>
    {comments.map(comment => (
      <li key={comment.id}>{comment.text}</li>
    ))}
  </ul>
);
}

How It Works

  1. Server starts sending HTML immediately
  2. When it hits <Suspense>, it sends the fallback
  3. Continues streaming rest of the page
  4. When data is ready, sends the actual component
  5. Client replaces fallback with real content
  6. Hydration happens independently per component

Selective Hydration

jsx
function App() {
return (
  <div>
    <header>Header</header> {/* Hydrates first */}
    
    <Suspense fallback={<Spinner />}>
      <HeavyComponent /> {/* Hydrates when user interacts */}
    </Suspense>
    
    <Suspense fallback={<Spinner />}>
      <Comments /> {/* Hydrates independently */}
    </Suspense>
  </div>
);
}

Benefits

  • Faster TTFB (Time to First Byte): User sees content sooner
  • Better UX: Progressive loading instead of blank screen
  • Prioritized hydration: Interactive elements hydrate first
  • Resilient: Slow components don't block fast ones

Next.js App Router Example

jsx
// app/page.tsx
import { Suspense } from 'react';
import ProductList from './ProductList';
import Reviews from './Reviews';

export default function ProductPage() {
return (
  <div>
    <h1>Product Page</h1>
    
    {/* Streams product list first */}
    <Suspense fallback={<ProductSkeleton />}>
      <ProductList />
    </Suspense>

    {/* Reviews stream separately */}
    <Suspense fallback={<ReviewSkeleton />}>
      <Reviews />
    </Suspense>
  </div>
);
}

// These are async Server Components
async function ProductList() {
const products = await fetchProducts(); // Doesn't block Reviews
return <div>{/* render products */}</div>;
}

async function Reviews() {
const reviews = await fetchReviews(); // Doesn't block ProductList
return <div>{/* render reviews */}</div>;
}

Key Requirements

  • Use React 18+ with createRoot and hydrateRoot
  • Wrap slow components in <Suspense>
  • Use frameworks supporting streaming (Next.js, Remix, etc.)
  • Server must support streaming responses