Yan Sun I am a full-stack developer. Love coding, learning, and writing.

Server-side rendering in Angular 16

6 min read 1866 105

Server-side rendering in Angular 16

Angular 16 was released on 3 May 2023, marking a significant milestone for Angular developers. In this release, one of the key innovations is non-destructive hydration for server-side rendering (SSR).

In this article, we will explore the new enhancements to SSR in Angular 16 and discuss its roadmap. Additionally, we will compare Angular’s SSR with React’s SSR, and provide a brief overview of Angular development in 2023. Jump ahead, if you like:

Before we delve into Angular SSR, let’s take a close look at client-side rendering (CSR) and server-side rendering in the context of a single-page app.


In a single-page app (SPA) using client-side rendering, the client application generates HTML within the browser using JavaScript. When the client app sends an initial request, the web server responds with a minimal HTML file to serve as the app container. The browser then proceeds to download and execute the JavaScript bundlers referenced in the HTML file to bootstrap the app.

CSR has a few disadvantages, including:

  • Blank page in initial load time: There is a delay before the JavaScript bundle is downloaded and the app is fully bootstrapped. During this time, users may see a blank page, which impact the user experience
  • Non-SEO friendly: Webpages relying on CSR mostly contain minimal HTML with links to the JavaScript bundle, so web crawlers may have difficulty in indexing the page content, which may result in reduced visibility in search engine results

SSR, however, addresses both the blank page issue and SEO concerns.

Using SSR, the HTML is generated on the server side, so the generated pages are fully formed and SEO-friendly. It also has a faster load time for the initial request, as the HTML is returned to the browser and displayed before JavaScript bundles are downloaded. Thus, when SEO and initial load time are priorities, SSR is the recommended option.

SSR with Angular 4 and Universal

Angular supports SSR through its Angular Universal package, a nickname for server-side rendering in Angular that refers to its ability to render at both the client and server sides.

First introduced in Angular 4, Angular Universal provides server-side rendering, including dynamic server rendering as well as static pre-rendering. However, this form of SSR had a few limitations due to its “destructive” nature.

To better understand how Angular Universal works, we need to have a look at the concept of hydration.

Angular’s destructive hydration

Angular hydration is the process of adding interactivity to a server-side rendered HTML page by adding event listeners and states. Efficient hydration is critical to user experience, but it is also challenging to implement as there are many moving parts to manage.

Before Angular 16, the hydration process in Angular Universal is destructive hydration. When a pre-Angular 16 app starts, the following events take place:

  1. The browser sends a request to a web server
  2. The web server immediately returns the DOM structure markup of the webpage
  3. The browser renders the initial version of the page markup, but it isn’t interactive yet, as the JavaScript hasn’t loaded
  4. The JavaScript bundles are downloaded in the browser
  5. The Angular client app takes over, loads the bundle, and is bootstrapped
  6. The whole page is reloaded

The above process is called destructive hydration because the client app discards the pre-rendered HTML and reloads the entire page.

It is worth noting that in step 3, the page displays some content known as the First Meaningful Paint (FMP). A quicker FMP is one of the primary benefits of SSR, particularly for performance-critical apps.

The problem of destructive hydration is page flickering, which happens when the server-side-rendered markup is replaced by the client-side rendered content. Multiple issues (i.e., 13446) have been opened in the Angular GitHub repo to resolve this, and it is considered to be a main limitation of the Angular Universal.

Angular 16: Non-destructive hydration

Angular 16 solves this problem by the introduction of non-destructive hydration. In non-destructive hydration, existing server-side-rendered DOM markup is reused. That means the server-side-rendered DOM markup isn’t destroyed; instead, Angular will traverse through the DOM structure, attach the event listeners, and bind the data to complete rendering.

Below is a comparison diagram to illustrate the difference between destructive and non-destructive hydration:

Destructive vs. non-destructive hydration
Destructive vs. non-destructive hydration

Another related improvement is that HttpClient has been updated to enable server-side request caching. This enhancement prevents redundant data retrieval on the client side by caching previously fetched data, resulting in better performance.

Applying SSR to an existing Angular app

In this release, Angular Universal provides more streamlined tooling support.

Assuming you have an existing Angular 16 app, we just need to run the following command to enable server-side rendering:

ng add @nguniversal/express-engine

This command will update your app to add a server-side application for SSR support.

To enable non-destructive hydration, we need to import the provideClientHydration function as the provider of AppModule:

import {provideClientHydration} from '@angular/platform-browser';
// ...

 // ...
 providers: [ provideClientHydration() ],  // add this line
 bootstrap: [ AppComponent ]
export class AppModule {
 // ...

If you open package.json, you will find a few new commands were added:

   "dev:ssr": "ng run angularSSR:serve-ssr",
   "serve:ssr": "node dist/angularSSR/server/main.js",
   "build:ssr": "ng build && ng run angularSSR:server",
   "prerender": "ng run angularSSR:prerender"

To test server-side rendering in your local, run this command:

npm run dev:ssr

The app is running in SSR mode now!

It is worth noting that the new SSR feature is available in developer preview, which means that although the feature is fully functional and polished, the APIs may change at any time, including possible breaking changes.

Angular roadmap for SSR

The Angular team has announced their plan for next steps. Angular Universal’s packages are going to be moved into the Angular framework for better developer experiences.

The Angular team is also exploring partial hydration and resumablity to enhance SSR, which we’ll explore in a bit more detail below.

Partial hydration

Partial hydration is when parts of the component tree are skipped during initial rendering, and hydrated later by user demand. This is in contrast to full hydration, where all the components in the page are rendered at once.

Partial hydration in Angular will be an exciting enhancement to the existing SSR approach, as it enhances performance and responsiveness to a greater extent.


To understand resumability, let’s look at the problem it tries to solve. In the hydration process, there is a period called the “Uncanny Valley”. As shown in the diagram below, the uncanny valley occurs when the page is rendered but is not interactive:

Diagram of the uncanny valley experienced during  resumability
Diagram of the uncanny valley experienced during resumability

The page will become interactive after all of the event handlers and application states are restored for the whole component tree. In the uncanny valley period, if the user tries to click a button or scroll the page, nothing will happen.

Resumability resolves this issue by serializing event handlers and state on the server and resuming it on the client on demand. For a resumable Angular app, if a user clicks on a button in the uncanny valley period, the button event handler will be downloaded directly and executed in the browser, without needing to download all the JavaScript bundles and walk through the whole component tree.

Although resumability is a great improvement, it is a complex feature to implement and may introduce additional constraints for developer experience. The Angular team indicates that they are exploring the direction of leveraging Angular’s new Signals feature to provide a solution.

Angular Universal is becoming more modern and powerful. But how does it compare with React?

Angular SSR vs. React SSR

Angular’s non-destructive hydration works in a similar way to React SSR. React provides a server-side API to render React components to HTML on the server. The React client app will receive those HTML files and make the app interactive by attaching event handlers and states. This process is called React hydration.

The implementation of React SSR with pure React is a very manual process. You need to implement a server-side app, make changes to client-side components, and manage extensive configuration changes.

In contrast, Angular Universal provides much more streamlined tools to support SSR. But since Angular Universal isn’t formally part of the Angular framework, it is probably fairer to compare it with a Next.js and React app, instead of pure React.

Using Next.js makes it much easier to support SSR in React. Below is a summary of its SSR features compared with Angular Universal:

Feature Angular + Angular Universal React + Next.js
Rendering strategy Supports CSR, SSR, and SSG (or pre-rendering) Supports CSR, SSR, and SSG (or pre-rendering)
Pre-rendering Supports SSG for the whole or part of a site, as well as generating pages with dynamic routes Supports SSG for the whole or part of a site, as well as generating pages with dynamic routes
Incremental static regeneration (ISR) No out-of-the-box support, but offers a third-party library called ngx-isr Supports ISR out of the box
Mixing SSR and SSG You need to write custom coded in server.ts to manage routes Allows you to choose SSR or SSG on a page-by-page basis

In summary, Angular 16 Universal brings SSR to a similar level as Next.js + React, but Next.js has more refined support in some features like ISR and mixing different rendering strategies.

Angular development in 2023

According to the Angular team, the Angular 16 release is the biggest Angular release so far. There are many new features introduced, covering areas in reactivity, SSR, and tooling updates.

Besides SSR, another heavyweight feature is Signals. Signals is a new way to manage state changes. It provides an alternative to RxJS and is much more intuitive and simple to use in many use cases. Since signals allow developers to run change detection in specific components, the runtime performance is significantly improved.

Other new features in the releases include:

  • Required component input
  • Automatic route params mapping
  • New DestroyRef injector
  • An esbuild dev server
  • Dependency injection debugging APIs
  • Improved documentation and schematics for standalone components
  • Support for Tailwind CSS and CSS isolation
  • Improved security and prevention of XSS attacks

Angular 16 has made big improvements in the performance and user experience of its applications. According to the Angular team, the Largest Contentful Paint (LCP) performance has improved by up to 45 percent using the enhanced SSR.

Angular 16 received a warm welcome from development communities: the RFCs received over 1,000 comments and over 2,500 combined thumbs up on GitHub.

In the last few years, Angular has faced strong competition from other JS frontend frameworks. However, the Angular 16 release injects new momentum into the framework by providing better performance, streamlined tooling, and improved developer experience.


Angular 16 is a groundbreaking release. The enhanced SSR delivers significantly better performance and sets the stage for further improvement. Furthermore, the introduction of Signals provides a new and more efficient way for Angular state management.

As Angular continues to evolve, developers can look forward to a better development experience in 2023 and beyond.

Experience your Angular apps exactly how a user does

Debugging Angular applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Angular state and actions for all of your users in production, try LogRocket. LogRocket Dashboard Free Trial Bannerhttps://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your site including network requests, JavaScript errors, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket NgRx plugin logs Angular state and actions to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Angular apps - Start monitoring for free.

Yan Sun I am a full-stack developer. Love coding, learning, and writing.

Leave a Reply