Introduction

Angular is one of the most popular JavaScript frameworks. Indeed, Angular is already used by millions of developers and companies around the world, and its adoption is growing.

In this article, we will learn about the latest features introduced in versions 8 and 9, in both Angular core as well as the Angular tooling: the new Ivy render, the Schematic and Builder APIs, the new build and test orchestration tool, Bazel, differential loading, etc. We will also discuss what the future of Angular has in store for us. Spoiler alert: it will be about a lightweight and faster runtime, performant, and faster apps and dev tools, and interoperability.

Growing Adoption Rates

In order to know how many developers are using Angular and understand the framework's rate of adoption, the Angular team uses the number of daily active visitors to the official documentation website at angular.io. The rationale behind this metric is that many companies use Angular to build applications that are used internally or behind a firewall or to build applications that are not exposed directly to the open Internet (e.g. Dashboards for connected cars). The only viable metric left, in order to measure Angular adoption, is daily unique visitors.

A few months back, the Angular team announced that the number of unique visitors to the official documentation website had exceeded 1.5 million and I am confident that this adoption will continue to grow with time.

A Complete and Integrated Framework

Why do developers love to use Angular? One of the reasons they keep coming back is that Angular is a framework -- in contrast with a library -- meaning that it offers a complete set of APIs and tools. Whether it's routes managements, form building and validation, internationalization (i18n), server-side rendering, unit testing, tools for developers via Angular CLI, animations, or UI components, Angular integrates all the necessary building block APIs for building modern web applications, from prototyping to deploying.

Release Cycle

Angular has adopted a 6 month release cycle, based on the Semantic Version standard. This will help bring new innovations and bug fixes as quickly as possible while giving the users a clear agenda so they can plan their updates. This release cycle is as follows:

1 to 3 minor versions for every major release.

Patch version almost every week for bug fixes.

Please note that the team also offers a Long-Term Support (LTS) policy:

Active support during the 6 months of a major version.

An LTS with bug fixes and security patches for 12 months.

If you would like to try out the next version at any given time, with its documentation, you can find it at next.angular.io

Automated Updates Procedure

You can easily use the Angular CLI to upgrade your application\'s dependencies to the latest version of Angular using the following command:

ng update \@angular/cli \@angular/core

You can also use the next tag to try the next (i.e. preview) version of Angular and provide feedback to the team:

ng update @angular/cli@next @angular/core@next

You can read more about these automated updates at update.angular.io.

The New Features of Angular 8

Differential Loading

This was one of the major features introduced in Angular 8. Differential loading is a technique where the browser decides which JavaScript version (ES5 or ES2015+) to load, parse, and execute based on its (the browser's) capabilities. In fact, most modern browsers (we call them evergreen browsers) do natively support some of the newest ECMAScript features. One of the features that plays a major role in differential loading is ES Modules.

Based on this simple observation, we then provide the browser with two sets of JavaScript files:

A set of files transpiled to ES2015, for modern browsers.

A set of files transpiled to ES5, for legacy browsers.

How does differential loading work? When we build our application using the Angular CLI, it inspects our tsconfig.json file to check which JavaScript version we're targeting. If our target is ES2015, the CLI runs two builds: one for ES2015 and one for ES5. Let\'s take the following tsconfig.json for example:

{ "compilerOptions": { "module": "esnext", "moduleResolution": "node", "target": "es2015" } }

Our target here is ES2015, thus the CLI will output the following index.html:

<!-- For modern browsers --> <script type="module" src="polyfills-es2015.js"></script> <script type="module" src="runtime-es2015.js"></script> <script type="module" src="style-es2015.js"></script> <script type="module" src="vendor-es2015.js"></script> <script type="module" src="main-es2015.js"></script> <!-- For Legacy browsers --> <script nomodule src="polyfills-es5.js"></script> <script nomodule src="runtime-es5.js"></script> <script nomodule src="style-es5.js"></script> <script nomodule src="vendor-es5.js"></script> <script nomodule src="main-es5.js"></script>

Please note that the differential loading feature is turned on by default in Angular 8 and you don\'t have to worry about it. However, if you encounter any issues related to this feature, you can still revert to the ES5 target.

The Angular team has been using this technique on angular.io and managed to save up to 40KB of files being loaded by modern browsers. Also, according to feedback from community members, they noticed improvements varying from 7-20%.

Dynamic Imports

Lazy loading parts of applications has always been one of the recommendations for better loading time. This can be accomplished by configuring the Angular router using the following code:

{ path: 'home', loadChildren: 'home/home.module#HomeModule' }

This syntax was specific to Angular, however, and not part of any web standard. Now, since most modern browsers do natively support ES Modules, the new lazy loading syntax uses the Dynamic Imports standard:

{ path: 'home', loadChildren: () => import('home/home.module') .then(m => m.HomeModule) }

Code editors such as VSCode and WebStorm can now validate and provide you with code completion for your module paths.

Please note that if you are updating via the ng update command the CLI will automatically update your old syntax to the new one.

Builder API

Similar to the Schematics API that allows us to customize the generated code when using the CLI, through commands such as ng new , ng generate , ng add , and ng update , and adding new commands, the new Builder API allows us to customize the behavior of the build commands such as ng build , ng test , and ng run . This way, we can execute tasks that can run before, during, or after the build process.

Some cloud providers have already started creating their own builders to help their users to easily and seamlessly deploy their Angular app. For instance, you can now easily deploy to Firebase using @angular/fire or to Microsoft Azure using @azure/ng-deploy.

Web Workers Support

If you have some logic in your application that does heavy computations, you should already be running these workloads on web workers. With the Angular CLI, you can automatically add and configure web workers to your components:

ng generate web-worker <existing-component-name>

Please note that the code running inside the Web Worker is your application's logic, not the Angular runtime!

Learn more about Web Workers and Angular from the official guide.

Telemetry

Version 8 of the CLI adds a new telemetry feature that helps the Angular team understand how developers use the CLI and debug critical issues. This telemetry feature is disabled by default and users have to opt-in and enable it in order to share anonymous usage data with the Angular team. This new API allows users to also plug-in their own analytics server and get the same collected data. The information such as RAM and CPU usage, the size of the bundles, and the CLI commands, then gets logged. You can read about the full list of dimensions here.

Angular Elements

Angular is embracing the Web Components standard thanks to Elements. With this new feature, it will be possible to package any Angular component as a Custom Element.

There are many use cases for this new approach to shipping applications. You could use Angular components within:

Server-side technologies, e.g. ASP.NET.

Static web pages and websites, e.g. a CMS.

Other front-end technologies, e.g. Vue.js.

Here is a quick example:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule, Injector } from '@angular/core'; import { createCustomElement } from '@angular/elements'; import { HelloComponent } from './hello.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule], providers: [], entryComponents: [HelloComponent] }) export class AppModule { constructor(injector: Injector) { const element = createCustomElement( HelloComponent, { injector }); customElements.define('x-hello', element); } }

Then simply use your Element as a Web Component:

<x-hello></x-hello>

Bazel: A New Orchestration Build and Testing Tool

Currently, the CLI uses webpack and ng-packagr to build our apps and library (and this is not going to change soon). However, these tools may show some performance issues when trying to build very large applications. Since version 8, the CLI has integrated a new experimental build tool called Bazel.

Briefly, Bazel is an orchestration build and test tool created by Google that has been used internally for more than a decade to build the 86+TB of data inside Google's gigantic mono repository, before they open-sourced it in 2015. Here are some of the benefits of Bazel:

It supports backend, front-end, and mobile technologies.

It can run tasks in parallel, locally, and on distributed farm machines.

It supports incremental builds and caching.

Learn about the other benefits.

In the context of Angular, the Bazel integration (under the ABC initiative) is meant to give the Angular build and test toolchain a massive boost in performance.

Bazel has already helped the Angular team reduce the Angular framework build itself from 1 hour to nearly seven minutes!

You can start experimenting today with Bazel in the CLI with the following command if you are starting a new application:

npm install -g @angular/bazel ng new my-app --collection=@angular/bazel

If you would like to add Bazel to an existing CLI application, use the following:

ng add @angular/bazel

Please note that as you are using the CLI, all the configurations will be automatically managed by the CLI. So, in theory, you wouldn't even need to learn about Bazel. However, Bazel is a fascinating technology and I highly recommend investing some time and learning it, in case you need to use it with other technologies!

Ivy: The New Renderer

In the last year, the Angular framework team started working on a new implementation of the renderer and template compiler, code named Ivy. The main goals of this full rewrite are:

Reduce the size of the generated bundles.

Reduce the compilation time.

Provide better debugging.

Improve static type checking inside HTML templates (thanks to the TypeScript Language Service).

In order to have the smallest size possible, all the public APIs can now be tree-shaked: lifecycle hooks, pipes, queries, DI, etc. Also, one thing to mention is that with Ivy everything will be compiled in AOT mode.

In Angular version 9, Ivy will be enabled by default. However, if you are using Angular version 8, you can already experiment with Ivy using the following command:

ng new shiny-ivy-app --enable-ivy

For existing apps, you can manually update the following files:

Enable Ivy in your tsconfig.json file:

{ "compilerOptions": { ... }, "angularCompilerOptions": { "enableIvy": true } }

Enable AOT mode in your main angular.json file:

{ "projects": { "my-app": { "architect": { "build": { "options": { ... "aot": true, } } } } } }

The Future of Angular

Disclaimer: the following opinions are based on some hypothetical ideas and vision that Misko Hevery shared at NgConf 2019.*

With the new Ivy renderer and how the internal core of Angular has been redesigned, this is going to open up a whole new world of techniques in order to optimize even more Angular applications. We can imagine having NgModule become optional, and directly loading components independently (assuming Zone.js will not be required anymore!). Another possible solution to explore is server-side rendering, allowing Angular applications to fully render server-side with state and have that state propagated and resumed from the browser instead of recreating the show state again on the client! With these techniques, it would be possible to drastically boost the Time-to-Interactive and thus make Angular applications load very fast.

With all the new features (and there are some more), the future of Angular will be about a lightweight and faster runtime, performant and faster apps and dev tools, and interoperability.

Stay tuned.