The Problem
Currently in Next.js, a route is either fully static or fully dynamic. If you have just one dynamic part (like a shopping cart), the whole page becomes dynamic. This means slower page loads even when most content could be static.
How PPR Solves It
PPR lets you mix static and dynamic parts in the same route
At build time, Next.js creates static HTML for as much as it can
Dynamic parts get wrapped in React Suspense boundaries
The static parts show up instantly while dynamic parts load
Real World Example
Think of an e-commerce product page:
Static parts: Navigation, product images, description
Dynamic parts: Shopping cart, personalized recommendations
Without PPR: Everything waits for dynamic data
With PPR: Static content appears instantly, cart and recommendations load after
How to Use It
Enable in config:
// next.config.js
{
experimental: {
ppr: "incremental";
}
}
Mark dynamic components with Suspense:
<Suspense fallback={<LoadingCart />}>
<ShoppingCart /> {/* Dynamic component */}
</Suspense>
The Benefits:
Faster initial page loads
Better user experience (see content immediately)
No waterfalls (dynamic parts load in parallel)
Single HTTP request (combines static and dynamic parts efficiently)
Big advantage (CDN caching)
Static Parts:
Fully cached on CDN
Distributed globally
Never needs to hit your server
Instant delivery to users
Dynamic Parts:
Can't be cached (by definition, they need fresh data)
Must be generated on the server
Streamed in after the static content
The smart part is how it works:
User requests page
CDN immediately sends static shell (navbar, layout, product info)
In parallel, server starts generating dynamic content
Dynamic content streams in without blocking the static parts