Angular Hydration Explained Simply - What Is It and Why Does it Matter?
If you're a web developer looking to optimize your Angular application's performance, you may have heard of "Angular Hydration." This process restores a server-side rendered application on the client, and improves performance by avoiding extra work to re-create DOM nodes.
However, while Angular Hydration offers many benefits, it also comes with some constraints and potential pitfalls. In this article, we'll take a closer look at Angular Hydration, its benefits, constraints, and how to use it effectively in your Angular application.
What is Angular hydration?
Angular Hydration is the process that restores a server-side rendered application on the client. It involves reusing the server-rendered DOM structures, preserving the application state, transferring application data that was already retrieved by the server, and other processes. The purpose of hydration is to improve application performance by reusing existing DOM elements, avoiding extra work to recreate them, and preventing visible UI flickers.
Imagine you have an Angular application that displays a list of blog posts. To improve the initial load time and SEO, you decide to implement server-side rendering (SSR) using Angular Universal. When a user requests your web page, the server generates the HTML content, including the list of blog posts, and sends it to the user's browser.
Without hydration, the browser would receive the server-rendered HTML, display it to the user, and then destroy and re-render the DOM when Angular initializes the client-side application. This could result in a visible UI flicker and negatively impact performance metrics like First Input Delay (FID) and Largest Contentful Paint (LCP).
With Angular Hydration enabled, instead of destroying and re-rendering the DOM, the client-side Angular application tries to match the existing DOM elements to the application structure at runtime. By reusing these existing DOM elements, Angular Hydration can prevent the UI flicker and improve performance.
For example, let's say the server-rendered HTML structure for the blog posts looks like this:
<div>
<h1>Blog Title</h1>
<ul>
<li>Post 1</li>
<li>Post 2</li>
<li>Post 3</li>
</ul>
</div>
When Angular Hydration is enabled, the client-side Angular application would recognize the existing DOM structure, match it with the application's structure, and reuse the DOM nodes instead of recreating them. As a result, the user would not see a UI flicker, and the performance of the application would be improved.
How to turn on Angular hydration
To enable Angular Hydration, you need to import provideClientHydration
from @angular/platform-browser
and add it to your application's bootstrapping providers list or your root app module's provider list.
Here's an example of enabling Angular Hydration using a root app module:
import {provideClientHydration} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
@NgModule({
declarations: [RootCmp],
exports: [RootCmp],
bootstrap: [RootCmp],
providers: [provideClientHydration()],
})
export class AppModule {}
Keep in mind that Angular Hydration imposes some constraints on your application, such as having the same DOM structure on both the server and client. Direct DOM manipulation should be avoided, as it may lead to errors during the hydration process. If necessary, you can use the ngSkipHydration
attribute to skip hydration for particular components that do not work well with hydration.
How do you use Angular hydration?
To use Angular Hydration in your application, follow these steps:
Set up server-side rendering (SSR): Before enabling hydration, make sure your application uses Angular Universal for server-side rendering. If you haven't set up SSR yet, follow the Angular Universal Guide.
Import provideClientHydration
: Go to your main app component or module and import provideClientHydration
from @angular/platform-browser
.
Add provideClientHydration
to providers list: Depending on your app's structure, add provideClientHydration
to the providers list either in the bootstrapping providers list or the root app module's provider list.
For bootstrapping providers list, use the following code: