How Next.js Partial Prerendering Works: A Deep Dive

Jomar M. blog author

Jomar M

How Next.js Partial Prerendering Works: A Deep Dive

Have you ever visited a website and seen content pop in at different times? Or perhaps you've experienced that frustrating "blank screen" while waiting for a page to load? These are common issues in web development, often stemming from the way pages are rendered. But what if we could combine the speed of static pages with the dynamic nature of interactive web applications? That’s the promise of Next.js Partial Prerendering (PPR), an experimental feature that’s changing how we think about rendering.


The Problem with Traditional Rendering

Dynamic Rendering

Dynamic rendering is like a restaurant that cooks every meal from scratch each time an order comes in. This approach builds a page for every user request, making it ideal for frequently changing or personalized content (e.g., e-commerce recommendations). However, it can be slow for pages with shared static content.

Static Rendering (Prerendering)

Static rendering is akin to a bakery preparing bread in advance, ready to serve at any time. It prerenders pages at build time and stores them on a Content Delivery Network (CDN). While great for static content (e.g., blogs), it lacks flexibility for personalization.

Single Paradigm Frameworks

Historically, frameworks forced developers to choose between static or dynamic rendering for their entire app. This "all-or-nothing" approach created friction, as many apps benefit from a mix of both rendering strategies.


The Need for Partial Prerendering

Modern applications require a mix of static and dynamic content. For example, a blog post may have a personalized code snippet or a dynamic navbar. Traditional approaches fall short:

  • Static rendering cannot personalize content.
  • Dynamic rendering is inefficient for mostly static pages.

Partial Prerendering (PPR) addresses this by combining the performance of static rendering with the flexibility of dynamic rendering.


How Partial Prerendering Works

PPR divides a page into two parts:

  1. Static Content: Pre-rendered at build time.
  2. Dynamic Content: Rendered at runtime.

Key Components

  1. React Suspense Boundaries: Dynamic components are wrapped in Suspense boundaries with a fallback UI.
  2. Build Time Prerendering: Static parts are prerendered during the build, while dynamic parts render fallbacks.
  3. Edge Network: Static content is pushed to a CDN for fast delivery.
  4. Runtime Dynamic Rendering: The server streams dynamic content as it becomes available.
  5. Client-Side Hydration: The browser hydrates static and dynamic components for interactivity.

Example

It’s like serving a pre-made salad immediately while the main dish cooks. Users get something right away, and the rest streams in when ready.


Under the Hood: The Magic of Dynamic IO and the Event Loop

Dynamic IO

Next.js identifies dynamic components based on Input/Output (IO) operations, such as async functions. If a component contains an async operation, it is marked as dynamic.

JavaScript Event Loop

The event loop processes async tasks. Next.js halts prerendering when it encounters dynamic boundaries, streams static HTML, and processes dynamic parts later.

Key Features

  • useCache: Caches data or JSX outputs to convert dynamic components into static ones when possible.
  • Dynamic Detection: Previously reliant on helper functions (e.g., headers()), Next.js now uses async as the marker for dynamic behavior.

Benefits of Partial Prerendering

  1. Improved Performance: Faster initial load times via CDN-served static content.
  2. Dynamic Content: Personalization and dynamic data on static pages.
  3. Reduced Server Load: Static parts reduce the server workload.
  4. Flexibility: Seamlessly mix static and dynamic content.
  5. Enhanced UX: Avoid "blank screens" by loading static parts instantly.
  6. Granular Control: Separate loading states for static and dynamic content.

How to Use Partial Prerendering

Steps

  1. Enable PPR: Update next.config.js to enable the experimental ppr option.
  2. Opt-in per Route: Add experimental_ppr = true to the route file.
  3. Wrap Dynamic Components: Use React Suspense for dynamic parts.

Note: PPR is experimental and not recommended for production.


Conclusion

Partial Prerendering is a game-changer for Next.js. By combining static and dynamic rendering, it optimizes performance while enabling personalization. Its use of Dynamic IO and the JavaScript event loop simplifies the development process and enhances the user experience. While still experimental, PPR is a promising innovation for modern web development

Let’s Build Something Great Together!

Ready to make your online presence shine? I’d love to chat about your project and how we can bring your ideas to life.