New journey of Angular v16

Posted on May 21, 2023
angularangularssrAngular version 16Angular updates and features

Angular version 16 has major changes that will greatly impact Angular's future, popularity, and the lives of Angular developers! There's no denying that every new version of Angular introduces many exciting features, and Angular 16 will be no different.

Angular is undergoing a sort of revival, and version 16 marks just the initial stage of this resurgence. Here are some notable transformations that can be expected in this release.

Non-Destructive Hydration With Server-Side Rendering :scream:

In the new full app non-destructive hydration, Angular no longer re-renders the application from scratch. Instead, the framework looks up existing DOM nodes while building internal data structures and attaches event listeners to those nodes.

It means that end user-facing applications where initial time and SEO are very important, could leverage the SSR with hydration. With Angular universal application, angular would now enable real non-destructive server-rendered applications.

What is hydration? Hydration is the process that restores the server-side rendered application on the client. This includes things like reusing the server-rendered DOM structures, persisting the application state, transferring application data that was retrieved already by the server, and other processes.

Why is hydration important? Hydration improves application performance by avoiding extra work to re-create DOM nodes. Instead, Angular tries to match existing DOM elements to the structure of the application at runtime and reuses DOM nodes when possible.

What are the advantages?

  • No content flickering on a page for end users
  • Better Web Core Vitals in certain scenarios
  • Easy integration with existing apps, in just a few lines of code

To get started it is as easy as adding a few lines to your main.ts:

We will discuss more about these in our next blog Server-side rendering (SSR) and hydration in Angular v16

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

...

bootstrapApplication(RootCmp, {
  providers: [provideClientHydration()]
});

Note: Without hydration enabled, server-side rendered Angular applications will destroy and re-render the application's DOM, which may result in a visible UI flicker.

Angular Reactivity :confused:

A brand new reactivity model of Angular which will help to improve performance and developer experience, is compatible with the current system.

Now the big question is why?

Angular discovered that scaling out Zone.js did not yield optimal solutions. Let's figure out why is that?

Currently, all change detection is managed and performed under the hood of the Zone.js library and triggering a change detection by listening to any event in the browser, so it is natural that if something is in one of the child components then the whole tree of dependencies will be re-evaluated. Even if your application's change detection is in OnPush mode, the change detection cycle will go through the entire tree, unlike the default mode, OnPush components with no change dependencies will not be re-evaluated. Therefore it is clear that the change of detection in Angular is not optimal and in order to solve this problem that the integration of Signal will help.

The concept of Signal has been embraced and effectively implemented in various frameworks such as Preact, Solid, and Vue for quite some time, and has a lot of good performance improvement.

With Signal, the change detection level is done at the level of the signal variable. Thus a change detection will be done at the component level only, it does not require traversing through the whole tree without the need for the Zone.js. Signals will Significantly improve interoperability with reactive libraries such as RxJS.

Note: In the future, Zone Js could be optional

Three reactive primitives - It helps to tell UI what data changes and when, It helps your application UI Sync with your data.

We will discuss more about these in our Angular v16 Signals - The New Reactivity Model

  • Signals A signal is a wrapper around a value that can notify interested consumers when that value changes. Signals can contain any value, from simple primitives to complex data structures.
const count = signal(0);

// Signals are getter functions - calling them reads their value.
console.log('The count is: ' + count());

To change the value of a writable signal, you can either .set() it directly:

count.set(3);

There is .update() and .mutate()which will help signal variables to compute.

  • Compute A computed signal derives its value from other signals. Define one using computed and specifying a derivation function:
firstName = signal('Jane');
lastName = signal('Doe');
fullName = computed(() => `${this.firstName()} ${this.lastName()}`);
  • Effect Signals are useful because they can notify interested consumers when they change. An effect is an operation that runs whenever one or more signal values change.
effect(()=> {
 localStorage.setItem('FullName', this.fullName());
});

Improved tooling with Standalone Schematics

ng new great-app --standalone
//OR
ng generate @angular/core:standalone
//OR
ng new --standalone

Router Update :heart_eyes:

By utilizing this functionality, the component will have direct access to the router data mentioned, making it unnecessary to retrieve these values using ActivatedRoute. Instead, we can simply utilize inputs.

Current Approach

@Component({
  ...
})
class SomeComponent {
  constructor(route: ActivatedRoute) { }
  data = this.route.snapshot.data['dataKey'];
  params = this.route.snapshot.params['paramKey']
}

New approach

@Component({
  ...
})
class SomeComponent {
  @Input() dataKey: string;
  @Input() paramKey: string;
  
  //or
  @Input() set dataKey(value: string){
    //react to the value
  };
  @Input() set paramKey(value: string){
    //react to the vaue
  };
}

New Development Server (Vite) + esbuild :star_struck:

The angular version now supports an optional new development server that is called Vite. Its Pre-bundling with Vite's ESbuild makes it 10 to 100 times faster than using any other JS bundler. This is because it helps improve page speed and convert CommonJS / UMD modules to ESM.

Vite + esbuild

To enable this we need to change angular.json

...
"architect": {
  "build": {                     /* Add the esbuild suffix  */
    "builder": "@angular-devkit/build-angular:browser-esbuild",
...

Vite uses HMR functionalities to keep track of changes in your application without reloading the full page. With the HMR API, the browser will only load the modified section of the page and still retain the application's state.

Other updates to Angular v16 :smile:

  • ngcc will no longer be supported :frowning: and no backward compatibility with the view engine. The introduction of the Compiler (ngcc) was aimed at supporting compatibility with previous versions that utilized the view engine. However, with the recent changes, support for the view engine will be discontinued, and only IVY will be supported going forward.
  • Angular packages no longer include FESM2015 and the distributed ECMScript has been updated from 2020 to 2022.
  • Required Input :scream:, making an input required will be a simple configuration object to be passed to the metadata of the input annotation.
@Input({ required: true }) name!: string;
  • NavigationEnd the routerEvent property now also accepts type NavigationSkipped

  • New DestroyRef injector :open_mouth: In Angular v16, a new provider called DestroyRef has been introduced. This provider enables the registration of destroy callbacks for a specific lifecycle scope.

@Component({
  selector: 'foo',
  standalone: true,
  template: '',
})
class FooComponent {
  constructor() {
    inject(DestroyRef).onDestroy(() => {
      // do something when the component is destroyed
    })
  }
}
  • Autocomplete imports in templates: import the corresponding implementation by just clicking quick fix :astonished:
  • Slowly Migration from Karma to Web Runner Tool :tired_face:
  • New to NgOptimizedImage: Directive that improves image loading performance by enforcing best practices. :smile:

Thanks for reading!


Posted on May 21, 2023
Profile Picture

Arun Yadav

Software Architect | Full Stack Web Developer | Cloud/Containers

Subscribe
to our Newsletter

Signup for our weekly newsletter to get the latest news, articles and update in your inbox.

More Related Articles