Telerik blogs

Angular Ivy, the next generation compilation and rendering for Angular, brings speed and size improvements. See what it can bring to your app.

Ivy is the codename for the next generation compilation and rendering for Angular. It brings speed and size improvements for build code and more. Ivy has been used since version 9 of the Angular framework.

In this article, we will look at the improvements that Angular Ivy brings to our Angular projects.

Angular Ivy Means Smaller Apps

Angular Ivy compiles apps for smaller than the previous generation Angular compiler.

Small apps are 30% smaller compared to the Angular 8 compiler. And large apps are 25-40% smaller compared to Angular 8.

Faster, More Efficient Testing

Running tests is faster with Ivy since all tests can be run after the first compilation.

Before Ivy, each time a test was run, the project had to be compiled beforehand. The compilation process added significant delays to the testing time before Ivy.

Debugging Tools

With Ivy, the ng global variable is available.

It lets us access various parts of an Angular component just by entering the variable’s properties in the browser dev console. We no longer have to insert unnecessary console.log calls or breakpoints to debug our Angular apps.

ng is only available in development mode. Therefore, outsiders can’t access ng with the production build.

For instance, we type:

const el = document.querySelector("app-root");

into our browser console to get the root Angular component’s element.

And then type in:

ng.getComponent(el);

to get the Angular component instance that the el element corresponds to.

We can also type in:

ng.getDirectives(el);

to get the directives added to the component that the el element renders from.

And we can run:

ng.applyChanges(el);

to run change detection on the component that el renders from.

ng has been available since the first Angular release. But, with Ivy, we can get the variable’s value directly.

Other ng methods include:

  • ng.getContext: gets the context of the embedded view like the elements rendered by *ngIf or *ngFor.
  • ng.getDirectiveMetadata: gets the metadata for a particular directive.
  • ng.getHostElement: gets the host element for a component or directive instance
  • ng.getInjector: gets the injector associated with the element, component or directive instance
  • ng.getListeners: gets the event listeners associated with the element that’s rendered by a component. Host listeners are not returned with this method
  • ng.getOwningComponent: gets the component that contains the DOM element
  • ng.getRootComponents: gets all root elements associated with the DOM element

All the methods listed take a DOM element as their argument.

Improved Style Merging and Handling

A clear order of precedence determines how style rules are applied with the Ivy compiler.

For instance, the [style.color] color style overrides color styles set in other places.

Previous compiler versions used timing of the style application to determine the latest styles, and there were no consistent rules for applying styles. This could cause problems since different styles could be applied when the timing was different.

Lazy Loading

Lazy loading means only content that’s shown on the screen is loaded, and this is done right before the elements are shown.

This improves rendering performance since only the parts of the app that are shown to the user are loaded, rather than loading the whole app, which may be very large.

Improved AOT Compilation

AOT compilation stands for ahead-of-time compilation. The Ivy compiler defaults to AOT because it is now faster than the just-in-time compiler that was used in previous versions.

Template Type Checking

Before Ivy, the component template had next to no type checking.

With Ivy, component data types are checked at build time to see if the component data types in the template matches the declared data type.

The fullTemplateTypeCheck controls whether templates have data type checking enabled. And this is now true by default.

For instance, if we assign a number to a boolean variable in our template, we’ll get an error from the Ivy compiler.

If we have something like:

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  title: string = "angular-test";
}

And we write:

app.component.html

<button (click)="title = 123">click me</button>

We’ll get a type error since title should be a string.

Rebuild Times

With Ivy, the rebuild process is made more efficient because it only looks at public APIs that are changed and rebuilds those. Before Ivy, any change would trigger a rebuild.

Changes in the internal details of the components, directives, modules, etc. won’t affect the builds.

Globalization

Globalization features are also improved with Ivy. Ivy lets us load globalization features at run time instead of having to register them at compile time. Also, multiple languages can be built into the same app bundle instead of having to keep them separate.

To add localization features into our app, we add the @angular/localize package. We run:

ng add @angular/localize

and follow the instructions to add the package with its dependencies. The required imports for the dependencies will be added.

Then we write:

main.ts

import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

import { AppModule } from "./app/app.module";
import { environment } from "./environments/environment";
import { loadTranslations } from "@angular/localize";

import "@angular/localize/init";

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch((err) => console.error(err));

loadTranslations({
  Welcome: "Welcome to {$appName}.",
});

to call loadTranslations with an object with the translations to load the translations.

Then we use the $localize tag with:

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  title: string = "test";
  welcome: string = $localize`Welcome to ${this.title}.`;
}

to call $localize on the Welcome to ${this.title}. string.

In app.component.html, we write:

{{welcome}}

to show the message.

loadTranslations loads the translations on runtime when compiled with Ivy, so the amount of data needed to load during initial load is reduced.

Conclusion

Ivy, the next generation compilation and rendering for Angular, brings speed and size improvements for built code and more—in use since version 9 of the Angular framework.

In addition, lazy loading makes our app download the bare essentials instead of the whole app until the parts that are shown are required to be displayed.

Also, it exposes the ng variable so we can inspect our components with various methods.

There are now defined rules for merging styles with the Ivy compiler so they no longer depend on when they were last applied.

More template data type checking also helps with catching mismatched data type bugs early in the development process.


About the Author

John Au-Yeung

John Au-Yeung is a frontend developer with 6+ years of experience. He is an avid blogger (visit his site at https://thewebdev.info/) and the author of Vue.js 3 By Example.

Related Posts

Comments

Comments are disabled in preview mode.