23 June 2025

Streaming, Suspense, and Hydration in Next.js Development

Blazity

Performance Optimization

This article explores streaming, suspense, and hydration in Next.js development, detailing their concepts, benefits, and implementation to optimize web application performance and interactivity.

Blazity team
Blazity team

The Expert Guide to Next.js Performance Optimization

This article is part of The Expert Guide to Next.js Performance Optimization, a comprehensive Ebook you can download for free here.


The guide covers every aspect of building fast, scalable web apps with Next.js, including:


- Code Splitting

- Streaming, Suspense & Hydration

- Next/Image Component

- Third-Party Scripts

- Font Optimization

- Rendering Strategies

- Core Web Vitals

- Infrastructure

- Real-life Examples

- How to Measure Web Performance

- Bundle Analysis.

The Expert Guide to Next.js Performance Optimization

This article delves into the concepts and benefits of streaming for faster content delivery and reduced user frustration, explains the process of hydration for achieving interactivity on server-rendered pages, and discusses the challenges associated with traditional hydration. Furthermore, it explores implementation strategies within the Next.js App Router, particularly focusing on how React Suspense enables progressive and selective hydration to mitigate performance overhead and enhance interactivity.

What Is Streaming, Suspense, and Hydration in Next.js?


What is streaming?

Streaming is a technique that allows you to break down the rendering process into smaller, manageable chunks. Instead of waiting for all the data to load before showing the full page, streaming lets your app render and send parts of the page as soon as they’re ready. This approach significantly improves your application's performance, as users can see and interact with content much faster

Why does streaming matter?

Nowadays, users expect instant results. Even a few seconds of delay can increase bounce rates and decrease conversions. Streaming addresses this challenge by:

  • Enhancing perceived performance by displaying critical content first.
  • Reducing user frustration by minimizing blank or loading screens.
  • Optimizing server efficiency by handling data transfer in chunks.


Improving SEO and conversions through faster load times.

What is hydration?

Hydration in web development refers to the process where a server-rendered or statically generated page becomes fully interactive on the client side. When using Server-Side Rendering (SSR), the server generates and sends the initial HTML to the client. At this stage, the page is functional but lacks interactivity powered by JavaScript.


Certain built-in browser features, such as links and standard HTML forms, continue to work without JavaScript. However, interactive components like modals, dropdowns, and dynamic state management require JavaScript.


Hydration occurs when the client-side JavaScript framework, such as React, loads and reuses the pre-rendered HTML instead of generating it from scratch. It reconstructs the component tree, associates the existing DOM elements with the corresponding React components, and attaches event handlers. Lifecycle effects (such as useEffect in React) are also executed, ensuring the application behaves as expected.


Once hydration is complete, the page is fully interactive, with the client-side framework taking over rendering and state management.


Hydration and Suspense


By wrapping individual components in <Suspense>, we break down the application into smaller units called Suspense boundaries. React can prioritize the hydration of these smaller chunks, starting with the most critical areas based on user interaction. This approach leads to quicker interactivity for essential components while other parts of the app load asynchronously. 


Important: The requirement for hydration is that the content rendered on the server and client must be identical. If it’s not, a hydration mismatch error is thrown. The error is minified in production environments, making it easy to miss, but it has a significant impact. If this happens, the whole page falls back to client rendering, which might cause a flash of content and slower Time to Interactive times. Common things that cause hydration errors are:


  1. Usage of typeof window conditional rendering in JSX.
  2. Local date formatting can be different than the one generated on the server if the client uses different date formatting rules.
  3. Any random values that are different each time you call a function e.g., Math.random().

In short, hydration is key to combining the best of both worlds: 

  • the speed of a statically generated website
  • and the interactivity of a single-page application (SPA). 


What is the problem with hydration, then?

Despite its benefits, hydration's downside is the complexity and extra overhead it adds to web applications. The entire app has to be rendered again in the browser and rehydrated, leading to longer loading times and increased resource usage. Slow hydration can also negatively impact the time it takes for the page to become interactive.


Here are the key issues associated with hydration in Next.js and similar frameworks:


  • Performance Overhead: The browser must download, parse, and execute JavaScript to rehydrate the page, increasing resource usage and load times.
  • JavaScript Bloat: Large applications can accumulate excessive JavaScript, slowing parsing and execution.
  • Delayed Interactivity: Content appears instantly (SSR/SSG), but interactions will not be available until hydration completes, frustrating users.



Let’s explore how to mitigate these issues in Next.js.

Implementation

To optimize the hydration process in Next.js, we can suspend non-essential parts of the UI using Suspense. This approach reduces the amount of JavaScript we have to request and ensures that the crucial parts of the page remain responsive and interactive without unnecessary delays.   

Progressive/Selective Hydration & Suspence

Progressive Hydration and selective Hydration are techniques with similar goals but distinct implementations. Progressive Hydration, generally based on criteria set by developers, determines which parts of the user interface (UI) are initially hydrated. This technique ensures that key UI components become interactive first, following the developer's understanding of application priorities.


Selective Hydration, builds upon Progressive Hydration by adding prioritization based on user interactions. It breaks down Hydration into smaller units called Suspense boundaries. By wrapping individual components in <Suspense>, React can suspend the Hydration of these smaller chunks, starting with the most critical areas based on user interaction. This technique leads to quicker interactivity for essential components while other parts of the app load asynchronously.


In the Pages Router, hydration required all JavaScript to be loaded and executed before the page became interactive. This often led to performance bottlenecks on content-heavy or complex pages, and there were no built-in optimization options.


Thanks to the Next.js App Router, we can now easily enable Selective Hydration for almost any part of a website by implementing Suspense to defer hydration of non-critical components.


Selective hydration breaks an app into smaller chunks wrapped in <Suspense> boundaries. Critical components needed for immediate user interaction, like navigation, are hydrated first, while non-essential (suspended) parts load asynchronously in the background.


This approach reduces perceived load time and improves the app's responsiveness, particularly in complex applications.


Key Features and Improvements


  • Streaming HTML

HTML is streamed to the client progressively as it's rendered on the server. When ready, components inside <Suspense> boundaries will have their content streamed in smaller units.


  • Prioritization of Hydration

Hydration is prioritized based on the order of user interactions and the natural rendering order of the component tree. React will first hydrate the nearest Suspense boundary that the user interacts with, ensuring critical functionality is available promptly.


  • Reduced Blocking

The Pages Router required hydrating the entire page before any interaction. With Selective Hydration, React handles boundaries in smaller chunks, avoiding the blocking of unrelated components.


Code

1
2import { Suspense } from 'react';
3import Comments from './comments';
4import Sidebar from './sidebar';
5import Spinner from './spinner';
6
7export const PageContent = () => {
8  return (
9    <main>
10      <h1>Welcome to the Blog</h1>
11      <Suspense fallback={<Spinner />}>
12        <Sidebar />
13      </Suspense>
14      <article>
15        <h2>Main Article</h2>
16        <p>Content of the main article...</p>
17      </article>
18      <Suspense fallback={<Spinner />}>
19        <Comments />
20      </Suspense>
21    </main>
22  );
23};
24

Explanation

  • Suspense with Server Components: The server-side data fetching ensures data is available before sending the initial HTML to the client. By wrapping components like Comments and Sidebar in <Suspense>, these sections can be loaded independently, with loading handled asynchronously.
  • Selective Hydration: Once the server-side HTML is delivered, only the necessary JavaScript is loaded, prioritizing hydration based on the user's immediate needs.


Keypoints

  1. Hydration adds performance overhead due to extra JavaScript, leading to JavaScript bloat, delayed interactivity, and resource-intensive downloads. However, fast initial pages still need to be served from the server.
  2. Progressive and Selective Hydration aim to improve performance by not hydrating the entire page simultaneously.
  3. React's Suspense feature allows breaking hydration into smaller chunks, enabling selective loading and prioritizing critical functionality.
  4. Next.js App Directory streams HTML progressively to the client, using Suspense boundaries to prioritize and hydrate content dynamically.



blazity comet

Get a quote

Empower your vision with us today
Brian Grafola, CTO at Vibes

“We are very happy with the outcomes and look forward to continuing to work with them on larger initiatives.”

Brian Grafola

CTO at Vibes

Trusted by
Solana logoVibes logoArthur logoHygraph logo
The contact information is only used to process your request. By clicking send, you agree to allow us to store information in order to process your request.