Skip to content
next.js questions

Next.js · 7 of 10senior~1 min

What is Partial Prerendering and how does streaming work in Next.js?

#rendering#performance#streaming

Partial Prerendering (PPR)

Earlier a route was either static or dynamic: one cookies() call made the whole page render on every request. With Partial Prerendering (on by default with Cache Components) a single route is split into two parts:

  • Static shell - everything that doesn't depend on the request, prerendered at build time and served from a CDN.
  • Dynamic holes - parts inside <Suspense> that read request data and stream into the same response.
tsx
export default function ProductPage() { return ( <> <ProductInfo /> {/* cached - part of the shell */} <Suspense fallback={<CartSkeleton />}> <Cart /> {/* reads cookies() - streams in */} </Suspense> </> ); }

How streaming works

  1. The server immediately sends the shell HTML with the fallback in place of each hole.
  2. As soon as an async component resolves, React sends its HTML in the same response with a small inline script that swaps it into place.
  3. Holes resolve independently: a slow block doesn't delay the rest of the page.

Benefits

  • Fast TTFB and FCP, as with a static page.
  • Personalized data without making the whole route dynamic.
  • loading.tsx is just a <Suspense> boundary around the page created by convention.

Note: <Suspense> itself does not make anything dynamic. Only access to request data or uncached I/O turns a component into a hole; synchronous code finishes during prerendering anyway.

updated

did you know it?

read more on the blog

view all

related questions