Incremental Hydration in Angular: Introduction (Part 1/3)
Table of Contents
Incremental hydration is a groundbreaking new feature in Angular that heavily impacts critical performance metrics like INP (Interaction to Next Paint) and LCP (Largest Contentful Paint), while also reducing the effort required to maintain CLS (Cumulative Layout Shift) at low levels. By deferring hydration to critical moments, this feature unlocks further refinements in Angular’s rendering capabilities—making apps load faster, respond more quickly to user input, and minimize visual shifts often caused by unnecessary DOM reflows.
In this series, we’ll break down the technical details, walk through the setup process, and explore real-world patterns and practical examples of incremental hydration to help you make the most of this advanced new capability.
A New Rendering Strategy
In recent releases, Angular's server-side rendering (SSR) has taken a transformative leap forward, paving the way for incremental hydration to become the framework’s most advanced loading and hydration mechanism on the market. Specifically designed to optimize core web vitals—such as LCP, INP, and CLS—this approach fundamentally alters how and when components hydrate on the client side. Instead of hydrating every component immediately, the framework can now choose to hydrate only the parts of the UI that truly need it, and at precisely the right time.

Comparing Reboot and Incremental Hydration in Angular
To fully appreciate the significance of incremental hydration, it's essential to understand how it contrasts with Angular’s traditional hydration method, also known as reboot.
Reboot
Reboot refers to Angular's conventional hydration process, where the entire application is hydrated on the client side after server-side rendering and the JavaScript load. This process typically follows this sequence:
Initial Load. Angular executes the application on the server, returning a fully rendered DOM in the index.html file. This allows the user to quickly see meaningful content.
Hydration Reset. As the browser downloads and executes the JavaScript bundle, Angular hydrates the application on the client side. This stage can effectively reset the application state, resulting in a brief period where the visible content is reprocessed. During this hydration reset, users may experience layout shifts or see parts of the UI flicker as Angular attaches event listeners and rehydrates components.
Complete Hydration. Once hydration is complete, all components are responsive to user interactions, and the app state is fully synchronized between server and client.
In essence, a reboot can leave users with a page that initially appears ready, only to reset as it hydrates—leading to visual inconsistencies and slow responsiveness.

Incremental Hydration
Incremental hydration, on the other hand, offers a more refined approach by postponing hydration until it’s absolutely necessary—such as when a user first interacts with a specific part of the app. This method helps to avoid the main-thread bottlenecks that often accompany a reboot and result in sluggish input responses and unexpected layout shifts.
The processes involved in incremental hydration include:
Server-Side Rendering. Angular builds an HTML-first version of your app. The initial view is generated on the server and then served to the user as a fully formed document.
Deferred Hydration. Once the static HTML is in place, Angular selectively hydrates only those components that require immediate interactivity. This leads to a faster time to first paint and keeps the main thread free to handle user interactions.
Event Replay. Angular can optionally record events until the relevant code is loaded and hydrated, ensuring the user’s actions aren’t lost in the process.
Seamless DOM Takeover. Incremental hydration seamlessly takes over the existing DOM without tearing down or rebuilding elements, maintaining visual stability and preventing layout shifts.
Hydration Process Breakdown
Incremental hydration effectively addresses the common challenges associated with both server-side and client-side rendering. By establishing a smooth transition from server-rendered content to a fully interactive application on the client side, this process sets a new standard for performance. The breakdown of the hydration process can be outlined as follows:

1. Build & Transfer
1.1 Application Build
Inject EventReplay logic 🔄
Add hydration marker 🔖
1.2 Server Rendering
Generate initial HTML
TransferState (+ 💧hydration state)
Critical CSS
(Pre-)rendering
1.3 Transfer to Client
Edge Cache
Streaming
2. Render & Load
2.1 HTML Parsing
Document Parsing
Request Prioritization
2.2 Client Rendering
Event initialization 🔄 (record/replay)
2.3 Resource Loading
(Pre)loading resources
3. Hydration & Replay
3.1 Initial Hydration
Take over DOM 💧
Wire global event listener
Stop event recording 🔄
3.2 Interaction
Record and replay 🔄events
3.3 Incremental Hydration
Wire global event listener
Stop event recording 🔄
Hydration Process In-depth
Having outlined the key steps involved in the hydration process, let's delve deeper into the core components that make incremental hydration in Angular so effective: event recording, state hydration, and event replay. Each one plays a vital role in ensuring that your Angular application remains responsive and maintains a seamless user experience during and after hydration.
Event Recording

When a user interacts with the application while it is still hydrating, Angular needs to ensure that these interactions are not lost. Here's how it works:
Global Queue of Events. As users interact with the application (e.g., clicking buttons, typing in input fields), these events are captured and placed into a global event queue. This queue temporarily holds all user actions before the relevant components are fully hydrated.
Marks and SSR DOM. Specific elements in the server-rendered DOM are marked (e.g.,
) to identify which components should handle these events once hydrated. These marks serve as placeholders, indicating where event listeners will be attached.<input jsaction="click:;">
Global Event Listener. A global event listener is wired up to monitor and record these events. This listener ensures that all interactions are captured accurately without interfering with the initial rendering process.
The arrows in the diagram indicate that the rendering process feeds back into event recording. As components hydrate, they attach their own event listeners, allowing them to process the queued events in the order they were received.
State Hydration

State hydration ensures that the client-side application accurately reflects the server-rendered state. This process involves synchronizing the application's state between the server and client, enabling a consistent and interactive user interface.
Hydration State. The server generates an initial state (e.g.,
) that represents the current status of various components. This state is embedded within the server-rendered HTML.{ 0: { isDark: true } }
Markers in SSR DOM. Specific markers (e.g.,
) are inserted into the server-rendered DOM. These markers link the hydration state to their corresponding components, ensuring that each component can retrieve and apply its state correctly during hydration.<dark-mode ngh="0" />
Angular State Synchronization. On the client side, Angular reads the hydration state from the embedded data and applies it to the corresponding components. This synchronization process ensures that the client-side application mirrors the server-rendered content accurately.
Event Replay

Event replay is the final step in the incremental hydration process, ensuring that all recorded user interactions are processed correctly once the relevant components are hydrated.
Global Queue of Events. As with event recording, user interactions are captured and stored in a global queue. These events are waiting to be handled by their respective components once hydration is complete.
Component Hydration. As Angular selectively hydrates components based on triggers (e.g., user interactions, idle times), each hydrated component retrieves the events from the global queue that pertain to it.
Event Handling. The arrows in the diagram illustrate the flow from the event queue to the specific components. Once a component is hydrated, it attaches its event listeners and processes the queued events in the order they were recorded. This ensures that no user interactions are missed or ignored, maintaining the application's responsiveness.

Looking Ahead
Incremental hydration sets a new benchmark for performance optimization in Angular. By using it wisely, you can:
Deliver faster-perceived load times
Reduce main thread blocking that might otherwise slow down user interactions
Avoid layout shifts by removing the need for placeholder elements
In Part 2, we’ll explore the impact of incremental hydration on performance metrics like LCP, INP, and CLS, and explain why it yields such dramatic improvements. Then, in Part 3, we’ll dive into a practical developer example that shows you how to implement incremental hydration in a real-world Angular application.