Streaming and Suspense

The app directory introduces support for streaming and React Suspense during server-rendering in both Node.js and Edge runtimes.

Concepts

Streaming allows you to incrementally send UI from the server to client, progressively rendering components and pages. This enables displaying content faster, without waiting for all data fetching to complete before the UI is rendered.

Streaming is particularly beneficial when there's a slow network request for retrieving data. Rather than the entire page being blocked from rendering due to a slow API or database lookup as seen below:

Server Rendering without streaming

UI can be incrementally sent to the client. Users don't have to wait for the entire page to load before they can start interacting with it.

Streaming components

With Next.js, your UI can be resilient to inconsistent network speeds. Fast requests can be streamed to the client as soon as they are ready. Slow, or inconsistent requests, can be wrapped in a Suspense boundary to show a fallback component until they've completed rendering on the server.

When using non-streaming server-rendering, the server is blocked from transferring data back to the client until it has completed rendering the entire page. Once the data is transferred to the client, the page is not interactive until the client-side JavaScript bundle is downloaded and executed.

Chart - Server Rendering without Streaming

With the app directory, components can be incrementally streamed in. This reduces both the Time To First Byte (TTFB) and First Contentful Paint (FCP) for displaying UI from the server.

Chart - Server Rendering with Streaming

Usage

You can stream UI in Next.js using loading.js (for an entire route segment) or with Suspense boundaries (for more granular loading UI).

Instant Loading UI

The special file loading.js enables showing an instant loading state from the server while the content of a route segment loads. Once all data fetching in the route segment has finished, the loading UI will be swapped for the page.

app/dashboard/loading.tsx
export default function Loading() {
  return <p>Loading...</p>
}
Server Rendering with Streaming

Suspense Boundaries

React Suspense boundaries enable granular loading UI for data fetching. Next.js will render content on the server and progressively send updates through HTTP streams to the client.

A Suspense boundary wraps a React component. While the component rendering is suspended, the fallback for the Suspense boundary will be shown.

app/dashboard/page.tsx
import { Suspense } from "react";
import { PostFeed, Weather } from "./Components";

export default function Posts() {
  return (
    <section>
      <Suspense fallback={<p>Loading feed...</p>}>
        <PostFeed />
      </Suspense>
      <Suspense fallback={<p>Loading weather...</p>}>
        <Weather />
      </Suspense>
    </section>
  );
}
Streaming components

Next Steps