Thuta Learning
IntermediateWeb Developmentintermediate

Streaming and Suspense

Relax. We'll talk through this in plain words — no textbook voice.

What you'll walk away with

  • Watch out for blocking renders
  • Add Suspense boundaries
  • Write meaningful loading fallbacks

Say a dashboard's user profile loads fast but its analytics loads slowly. If you wait for analytics before rendering the whole page, the user just stares at a blank screen. Streaming sends the ready parts first and fills in the slow part later.

The mental model

A Suspense boundary wraps an async component with a fallback. The server ships the page shell first, then streams in updates as each component's data finishes loading. loading.tsx is great for a whole route, while Suspense is more precise for a smaller piece within a page. If the fallback is a skeleton that matches the size of the incoming UI — rather than just a line of loading text — you get less layout shift.

Let's build it together

tsx
import { Suspense } from "react";

async function SlowNotes() {
  const notes = await getSlowNotes();
  return notes.map((note) => <article key={note.id}>{note.title}</article>);
}

export default function NotesPage() {
  return (
    <main>
      <h1>မှတ်စုများ</h1>
      <Suspense fallback={<p>မှတ်စုစာရင်း ဖွင့်နေသည်…</p>}>
        <SlowNotes />
      </Suspense>
    </main>
  );
}

How the code works

NotesPage's heading renders instantly, and only SlowNotes waits inside Suspense. Since the promise isn't awaited in the parent, streaming can actually happen.

You should see
The heading appears first, followed by a loading fallback, and then the note list fills in.

5-Minute Try-It

Write a page with a profile and an activity list, and stream only the activity list with Suspense.

Next.js — Fetching DataNext.js

Easy traps

  • Awaiting a data promise outside Suspense, which throws away the streaming benefit
  • Using a fallback that's a mismatched size and causing layout jumps

Exercise

Write a page with a profile and an activity list, and stream only the activity list with Suspense.

You'll know it worked when: The heading appears first, followed by a loading fallback, and then the note list fills in.

Streaming and Suspense | Thuta Learning