One of the main goals in modern Angular apps is reducing hydration costs and improving user experience. With Angular v19, we finally get native tools to achieve this: Incremental Hydration and Event Replay.
In Part 1, we explored the fundamentals of @defer blocks and triggers. Now, let’s see how Angular extends that foundation to make hydration smarter and interactions smoother.
💧 Incremental Hydration
Hydration is the process of transforming a pre-rendered HTML page (generated by server-side rendering) into a fully interactive Angular app on the client side.
Incremental Hydration takes this a step further by letting you control when specific parts of your application should become interactive.
This means better Core Web Vitals, faster initial paints, and a smoother user experience overall.
Activate it like this:
export const appConfig: ApplicationConfig = {
providers: [
// other providers
provideClientHydration(withIncrementalHydration())
]
};
Once configured, you can start deferring hydration for parts of your UI:
@defer (hydrate on idle) {
<large-cmp />
} @placeholder {
<div>Large component placeholder</div>
}
The hydrate syntax mirrors the classic @defer structure, supporting the same triggers and patterns. You can even combine behaviors:
@defer (on idle; hydrate on interaction) {
<large-cmp />
} @placeholder {
<div>Example Placeholder</div>
}
Note: The on interaction trigger behaves differently when used with hydrate. Classic @defer requires an element reference, while hydrate doesn’t—the interaction happens directly with the de-hydrated version of the component.
Example:
<!-- Classic @defer -->
<div #greeting>Hello!</div>
@defer (on interaction(greeting)) {
<greetings-cmp />
}
<!-- @defer with hydrate -->
@defer (hydrate on interaction) {
<greetings-cmp />
}
With hydrate, the component itself is the trigger, simplifying setup and making it easier to use in real-world hydration scenarios.
Why it matters
Incremental Hydration is especially valuable for large apps with multiple deferred views — dashboards, content-heavy pages, or e-commerce layouts. It helps you decide when to activate interactivity, improving both performance and responsiveness.
⚡ Event Replay
Server-Side Rendering (SSR) is key for performance and SEO, but it introduces a common problem: lost interactions.
When HTML is pre-rendered, users can start clicking before the JavaScript is fully hydrated. Without proper handling, those interactions are lost — leading to broken UX.
Event Replay fixes this by capturing events during hydration and replaying them in the same order they occurred.
This ensures every user action is processed, even if it happened before the app became interactive.
Activate it with:
export const appConfig: ApplicationConfig = {
providers: [
// other providers
provideClientHydration(withEventReplay())
]
};
If you’re already using withIncrementalHydration(), you don’t need to add withEventReplay() separately—it’s included automatically.
Why it matters
Event Replay ensures that no user action is lost. It captures input events (like clicks, scrolls, or typing) and replays them after hydration. The result is a seamless, frustration-free experience for users.
🧩 Combined Example
Here’s how both features can work together:
export const appConfig: ApplicationConfig = {
providers: [
provideClientHydration(withIncrementalHydration())
]
};
@defer (hydrate on interaction) {
<user-profile />
} @placeholder {
<loading-spinner />
}
In this example, Angular hydrates the user-profile component only after the user interacts with its placeholder. Any clicks made before hydration are safely replayed, thanks to Event Replay.
🧠 Behind the Scenes
Under the hood:
- Incremental Hydration reuses the server-generated DOM and attaches event listeners lazily.
- Event Replay hooks into the browser’s event queue, caching early interactions and re-dispatching them once hydration is complete.
These optimizations work together to provide a faster, more resilient user experience especially in apps with complex, interactive UIs.
🪄 Key Takeaways
- Incremental Hydration lets you decide when to make parts of your app interactive.
- Event Replay ensures no interaction is lost during hydration.
- Combined, they improve Core Web Vitals, reduce Time to Interactive, and simplify performance optimization in Angular.
- 👉 Try it live on StackBlitz to see Incremental Hydration and Event Replay in action! Core Web Vitals, reduce Time to Interactive, and simplify performance optimization in Angular.
If you found this helpful, follow me here and on LinkedIn for more deep dives into Angular, web performance, and modern frontend development.
See you in the next one! 🤙🏻
— G.
Top comments (0)