How Angular SSR works with non-destructive hydration

How Angular SSR works with non-destructive hydration

Angular SSR with non-destructive hydration explained

Since Angular 16 we can use server side rendering (SSR) in combination with non-destructive hydration. We will take a deep dive into how SSR and non-destructive hydration work.

SSR with Angular

Server side rendering (SSR) involves rendering web pages on a server rather than in the browser. In a typical single page application (SPA), pages are loaded and rendered within the browser. While browser rendering offers flexibility, it also has drawbacks, notably slower performance and sub optimal SEO.

Using server side rendering (SSR), improves page load times and SEO performance. However, SSR often results in heavy page reloads, disrupting the user experience (UX) we value in SPA frameworks. To address this, Angular has new features in V17 that first render the page on the server. As the browser displays the page, Angular gradually replaces the server-side rendered page with a standard SPA page rendered in the browser.

This approach introduces issues such as UI flickering when switching from the SSR page to the browser-rendered page. It also contributes to delayed First Input Delay (FID) and Largest Contentful Paint (LCP), both critical performance metrics.

Angular SSR with Hydration comes to the rescue

To address these issues, Angular has introduced non-destructive page hydration. With hydration, Angular avoids rebuilding the entire page in the browser after rendering the server side rendered (SSR) page. Instead, it compares the DOM structure with the server-side rendered page and reuses as many DOM elements as possible. This approach aims to minimize the overhead of recreating all DOM elements.

Implementing hydration results in a further increase in performance. Tests show that hydration is up to 45% faster than a standard SSR application. It also helps reduce UI flickering, contributing to an improved user experience (UX). However, it's important to note that hydration is not a perfect solution. There are associated drawbacks as well.

Limitations of SSR with hydration:

  • The application must maintain identical DOM structures on the server and client. Failure to do so may result in errors.

  • Direct manipulation of the DOM, such as modifying elements using methods like appendChild(), can cause problems and is discouraged.

  • It is mandatory to adhere to valid HTML structures. Some common incorrect HTML structures are:

      <table> without a <tbody>
      <div> inside a <p>
      <a> inside an <h1>
      <a> inside another <a>
    
  • The preserveWhitespaces setting in your tsconfig must be set to false (the default) to avoid complications with hydration.

  • CDN optimisations, particularly the removal of unused DOM nodes, may cause problems.

  • It's important to note that custom or Noop Zone.js configurations are not currently supported.

import {
  bootstrapApplication,
  provideClientHydration,
} from '@angular/platform-browser';
...
bootstrapApplication(AppComponent, {
  providers: [provideClientHydration()]
});
import {provideClientHydration} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
@NgModule({
  declarations: [AppComponent],
  exports: [AppComponent],
  bootstrap: [AppComponent],
  providers: [provideClientHydration()],
})
export class AppModule {}

Conclusion

Angular takes a step forward with the new SSR, leaving the Angular Universal behind and introducing stable hydration. These steps have put Angular at the forefront of SSR frameworks and this hydration model takes it one step further.

https://angular.dev/guide/ssr

https://angular.dev/guide/hydration

Did you find this article valuable?

Support Rubén Peregrina by becoming a sponsor. Any amount is appreciated!