Kacper Drzewicz
Kacper Drzewicz
Senior Software Engineer

Next.js 16 Partial Prerendering (PPR): The Best of Static and Dynamic Rendering

Feb 11, 20263 min read

Next.js has long been a leader in giving developers flexible, high-performance rendering strategies - Static Site Generation (SSG), Server-Side Rendering (SSR), Incremental Static Regeneration (ISR), and Client-Side Rendering (CSR) all play roles depending on your use case. With Next.js 14, Partial Prerendering (PPR) was introduced as an experimental feature, starting from Next.js 16, PPR has become a stable and becomes a foundational part of this landscape by letting you blend static pre-rendering and dynamic behavior in the same route, improving perceived performance and SEO without sacrificing real-time data needs.

What Is Partial Prerendering (PPR)?

Partial Prerendering is a rendering strategy that lets Next.js deliver a static HTML “shell” immediately, then stream in dynamic content as it becomes available - all in the same server response. Instead of choosing static or dynamic at the page level, PPR combines both on a per-component basis.

  • The static shell (layout, logo, product titles, navigation) is pre-generated at build time or cached ahead of requests.
  • Dynamic parts (cart state, recommendations, session data) load later and are streamed to the client using React’s <Suspense> boundaries.
  • Users see meaningful UI immediately, with dynamic content filling in seamlessly.

This leads to faster Time to First Byte (TTFB) and a smoother perceived experience, while still allowing data personalization and real-time updates.

How Partial Prerendering Works in Next.js 16

Cache Components: The Heart of PPR

In Next.js 16, PPR isn’t just an experimental flag - it’s integrated into the Cache Components system. Cache Components lets you opt-in to cache certain components or data instead of rendering them on every request, making pre-rendering more predictable and performant.

  • cacheComponents: true in next.config.ts enables PPR and component-level caching.
  • The new "use cache" directive lets you mark data-fetching functions or components as cacheable.
  • Anything not cacheable or depending on request-specific data can be wrapped in a <Suspense> fallback.

This approach gives you fine-grained control: static UI is reused across requests, while dynamic parts rehydrate or stream in only when needed.

Streaming and Suspense: The Engine Under the Hood

React’s <Suspense> plays a key role in PPR:

  • Wrap dynamic components in <Suspense> with a fallback UI (like a skeleton loader).
  • During rendering, Suspense tells Next.js where to halt pre-rendering and stream dynamic content later.
  • The server sends the pre-rendered shell immediately and then streams dynamic sections in parallel as they’re ready.

This strategy avoids blocks in page delivery and reduces the “white screen” effect often seen in traditional SSR or CSR approaches.

Why PPR Matters for E-commerce

For e-commerce platforms, performance directly impacts sales and SEO - factors also emphasized in the U11D articles about rendering strategies. A slow page can hurt conversions and search rankings. Partial Prerendering improves this by:

  • Faster initial loads: Users see the page skeleton instantly, improving engagement and performance metrics.
  • SEO advantages: Static content is available for crawler indexing immediately.
  • Dynamic personalization: Cart contents, recommendations, user-specific prices or availability can appear without blocking the initial render.
  • More flexible than SSG/SSR alone: You’re not limited to fully static or completely dynamic pages - the best of both lives together.

In e-commerce apps where product detail pages might be static for most users but show personalized recommendations or inventory status, PPR is a compelling hybrid.

How to Enable and Use PPR in Next.js 16

  1. Enable Cache Components:

    In your next.config.ts:

    import type { NextConfig } from 'next'; const nextConfig: NextConfig = { cacheComponents: true, // enables Partial Prerendering }; export default nextConfig;
  2. Wrap dynamic UI:

    Use React’s Suspense for dynamic content:

    import { Suspense } from 'react'; export default function ProductPage() { return ( <> <Header /> <Suspense fallback={<div>Loading product...</div>}> <ProductDetails /> </Suspense> </> ); }
  3. Use use cache for predictable dynamic data:

    Inside dynamic data functions, prefix with "use cache" to mark them cacheable:

    'use cache'; const product = await getProduct(id);

    This tells Next.js that caching is safe for that data.

How PPR Fits with Other Rendering Strategies

Partial Prerendering doesn’t replace SSR, SSG, ISR, or CSR - but coordinates with them. While U11D’s articles give a great overview of traditional strategies like SSG, SSR, and ISR, PPR adds a hybrid strategy that sits between:

  • SSG/ISR: Good for full static pages or pages that regenerate occasionally.
  • SSR: Ideal for real-time personalized content.
  • CSR: Great for highly interactive client-heavy UI.
  • PPR (Next.js 16): Combines static cached shells with streaming dynamic content.

Think of PPR as a component-level SSG + dynamic hybrid - fast to load like SSG, flexible like SSR.

Wrapping Up

Next.js 16 elevates Partial Prerendering from an experimental concept to a practical, integrated performance strategy through Cache Components and React Suspense. It’s especially powerful for complex, dynamic sites like e-commerce stores, where you want the benefits of static pre-rendering and dynamic personalization without sacrificing UX or SEO.

By serving instantly usable HTML and streaming dynamic parts in parallel, PPR bridges the traditional divide between static and dynamic rendering - helping your app feel faster while staying robust and scalable.

If you’re building with Next.js 16, definitely explore PPR alongside other strategies like SSR, ISR, and CSR to find the most performance-optimized combination for your routes.

RELATED POSTS
Michał Miler
Michał Miler
Senior Software Engineer

AWS Amplify vs Vercel: Complete Pricing Comparison for Next.js Applications

Feb 09, 20268 min read
Article image
Michał Miler
Michał Miler
Senior Software Engineer

Next.js 16 SSG on AWS Amplify: A Practical, Cost-Effective Deployment Guide

Jan 30, 20265 min read
Article image
Paweł Sobolewski
Paweł Sobolewski
Senior Software Engineer

React Server and Client Components in Next.js: Understanding the Difference

Dec 10, 20254 min read
Article image