Wednesday, June 17, 2020

Angular 8.0 Has Arrived: What to Expect and How to Upgrade?


What to Expect in Angular 8?

Compared to Angular 7, there are a whole lot of performance and workflow improvements in the latest version of Angular 8. Developers can look forward to Ivy – the eagerly-awaited, third-gen renderer along with other goodies like CLI APIs, differential loading, web worker support, and more.

This major release spans the entire platform and aligns it to the ecosystem. It covers the framework as well as Angular Material and goes on further to improve application loading speed on modern browsers.

With smaller bundles and higher order components, you can expect better debugging and quicker compilations without the need to repeat codes.

Here are the Highlights of Angular 8

Differential Loading by Default

From now on, Angular will serve different browsers with different bundles by default. The CLI extension will generate distinct bundles for old legacy (ES5) browsers and modern JavaScript (ES2015+) browsers.

This is known as differential loading, where browsers will select optimized or legacy bundles according to their capabilities and load the correct one automatically. Also, users will receive the bundle they require.

Overall, this will contribute to the build process and speed up applications via modern syntax and smaller amount of polyfills. The loading speed of modern browsers will get a boost and Time to Interactive will turn quicker. It is amazing how on modern browsers, differential loading can save up to 7-20% in bundle size on an average.

A part of Manfred Steyer’s project ngx-build-modern, differential loading in Angular 8.0 is the prime performance improvement in the update. It demands no special action; the ng build command with the –prod extension does the entire bundling.

Wondering how it works?

At present, when you utilize ng update, Angular updates the tsconfig.json. Thereafter, the CLI scans the target JS level in this to ascertain if differential loading is to be leveraged. With a target set to es2015, two bundles are generated and labeled. The right bundle is chosen in this manner:

<script type="module" src="…"> // Modern JS
<script nomodule src="…"> // Legacy JS

During runtime, modern JavaScript browsers would recognize a module type in the script tag of HTML and set aside any nomodule attribute. Thus, it will load only the bundle exclusive for modern browsers. Likewise, an older legacy browser would interpret the nomodule type and ignore any module attribute. Therefore, it will end up loading legacy bundles only.

Lazy Loading with Dynamic Imports

Lazy loading has been custom to the router and was built into the toolchain since the very birth of Angular. The loadChildren key in the route configuration is used to accomplish the same.

Up until now, it looked like this:

{path: '/admin', loadChildren: './admin/admin.module#AdminModule'}

However, Angular 8.0 has ditched custom string and welcomed industry-standard dynamic import syntax instead.

Post upgrading, a lazy loaded import will now look like this:

{ path: `/cart`, loadChildren: () => import(`./cart/cart.module`).then(m => m.CartModule) }

The syntax change will automatically work for you if you have used the ng upgrade command for your app. This improvement will boost support from the editors VSCode and WebStorm, who would be able to evaluate and validate the imports. Also, TypeScript and linters will be able to detect missing or misspelled modules better.

Improved Support for Web Worker Bundling

When you are into CPU-intensive tasks, web workers are the best way to speed up application and improve their parallelizability. They write code off the main thread and offload tasks to a separate background thread.

There is a catch, though. The code running in the web worker cannot exist in the same JavaScript file in an application. The two have to be discreet. It is frustrating for those working with tools such as Angular CLI that bundle JavaScript automatically into as fewer files as possible.

Now, the new improvement is kind of refreshing. Angular 8.0 enables fully parallelized web worker bundling without the aforementioned awkwardness. This is also a big relief for front-end developers who previously struggled because of single thread limitations.

To generate a new web worker from CLI and add it to your project, you can run

ng generate webWorker my-worker

When you receive your web worker, implement it in your application following the usual process. The CLI therein will bundle and code split it as required. Here’s a glimpse:

const worker = new Worker(`./my-worker.worker`, { type: `module` });

Opt-In Usage Sharing

This is yet another interesting addition to the Angular CLI which seems like an effort to align Angular 8 with the community needs. With this, the open-source web application framework will collect anonymous data only when allowed to.

Information such as commands used and build speed will help Angular keep a tab on how developers use the platform and how more improvements can be brought about. This is also your opportunity to share telemetry about CLI usage with your developer team.

This is a commendable effort, where Angular has emphasized on consent about data sharing so the development tool can be improved. Most other platforms collect data by default on an opt-out basis and stop only when you command them not to. Yet others don’t even allow you to ask them to stop sharing telemetry. To that end, Angular has found the correct way to do it!

Support for TypeScript 3.4

Angular 8.0 has not only welcomed TypeScript 3.4, but also mandated it. In other words, you will now have to update your TypeScript version without failing.

This update of dependencies on the tool is a way to synchronize it with the existing ecosystem. Although this seems like an insignificant improvement, it has greater benefits when it comes to generating clean, readable JavaScript codes.

Dart-sass for Sass Files

Yes, Angular CLI has ditched node-sass for dart-sass to create your Sass files. This would now be the reference implementation replacing Ruby – the legend. Dart is believed to be super fast almost to the point of notoriety.

Although the generated Sass files should remain unchanged, there are chances the compiler might become a tad stricter. Also, with fibers, the speed could double.

All this was possible earlier as well. However, Dart is now the default and that’s quite a change. Here’s a takeaway: node-sass can still be used if you install it explicitly.

Builder APIs and Workspace APIs in the CLI

The new Builder APIs will let you tap into ng buildng test and ng run much like Schematics lets you tap into ng newng generateng add and ng update. This will help you with processes such as build and deployment using third-party libraries and tool.

This apart, Angular is also working toward leveraging the cloud for APIs. The latest AngularFire, for instance, adds a deploy command, simplifying the process of build & deploy to Firebase.

ng add @angular/fire
ng run my-app:deploy

Furthermore, modifying angular.json in Schematics to bring about changes in the workspace configuration was previously a manual task. However, Angular 8.0 comes with a new API that makes modifying and reading the file a lot simpler.

Changes in ViewChild and ContentChild

Earlier, ViewChild and ContentChild were two nasty, inconsistent things. They were implemented so components could request elements that were not in a structural directive, such as ngIf or ngFor.

The query result for the same was ready in ngOnInit or accessed by the program code in ngAfterViewInit or ngAfterContentInit.

Also, for elements exclusively loaded later into the DOM because of data binding, the code had to insert either ngAfterViewChecked or ngAfterContentChecked. Needless to say, all this was extremely confusing.

Thankfully, with the new Angular version, the components have to specify exactly when a resolution has to take place. There are two scenarios:

@ViewChild('info', { static: true })
paragraph: ElementRef;

When the static value is true, Angular would find the element, which is not inside the structural directive, while initializing the component.

@ViewChild('info', { static: fasle })
paragraph: ElementRef;

When the static value is false, the view gets initiated or refreshed first, followed by the resolution taking place. The ng update command will automatically enter here or add a comment with a TODO if it fails.

Nevertheless, queries with ViewChildren and ContentChildren would remain unaffected and dynamic.

Improvements in AngularJS Migration

Users of the $location service should rejoice because Angular now enables a LocationUpgradeModule in AngularJS applications, which translates to a unified location service.

The latter smoothly shifts its responsibilities from AngularJS $location to Angular Location, thus easing it for applications with hybrid operations that depend on ngUpgrade and route in AngularJS as well as Angular part.

Bazel – the Buzzword

With Angular 8.0, it could be now possible to build CLI application more easily. How? – Because Bazel is here again! Developed and used by Google, this build tool can function with almost any language input.

In fact, the entire Angular framework is Bazel-born! Here are some of the key benefits:

  • You can use the same tool for building backends and frontends.
  • There is every possibility to get remote builds and cache on build farm.
  • It enables you to declare tasks with a clear input and output, running only the ones necessary.
  • It allows incremental builds and tests, thus bringing gains on rebuild times.

What is all the Hype about Ivy?

This is the biggest of the lot and the core of all the frenzy about Angular 8.0. Yes, Ivy is the prime feature of this release.

It was earlier announced in Google I/O 2018 by Kara Erickson, who is now associated with Angular. It has been the talk of the developer town since.

In layman’s terms, this new compiler is meant for building the next-gen rendering pipeline for the latest Angular version, thus rendering it more efficient. It is able to generate significantly smaller bundles which simplifies incremental compiling, thereby improving runtime speed.

On the technical front, it makes use of incremental DOM where each component gets compiled with instructions, which, in turn, contribute to the DOM tree.

Its two primary concepts include:

  • Tree shakable: Unused code is removed so application concentrates on the code it is using. This results in smaller bundle and faster runtime.
  • Local: Only the components that change are recompiled. This results in quicker compiling.

Whenever there is a data change, it would automatically update. So, if UI of your application is dear to you, Ivy should excite you to the utmost.

Advantages of Angular 8 Ivy

  • Smaller bundles
  • Decreased payload size
  • Pre-compiled code shipment
  • Enhanced backwards compatibility
  • Faster rebuild times
  • Improved template type checking
  • Dismissal of metadata.json
  • Emergence of meta programming
  • Broad compatibility with existing Angular applications

Currently, Ivy is included in Angular 8.0 only as an opt-in preview for testing. Angular developers can try it out to determine the potential and performance of their Angular application. Once it is completed, it will make such applications simpler, smaller and faster than before.

Moreover, all this would be achieved without altering anything in the existing application. To cut the long strong short, Ivy is the futurism we can hope to witness within the Angular world.

How to Update from Angular 7 to 8?

As always, updating from Angular 7 to 8 is an easy breezy thing. This is true especially if you have already started using the latest HttpClient and upgraded to RxJS 6.

In fact, for most developers, running this single command should automatically migrate the lazy loaded route imports to the new import syntax:

ng update @angular/cli @angular/core

Here are a few things to consider while upgrading to Angular 8:

  • Syntax errors might emerge due to the presence of TypeScript 3.4. This might lead to some issues which previously didn’t occur.
  • You would need to use Node.js version 12 or later without failing. Run the $ node -v command to check which Node version you are using. If it’s an old one, better update at the earliest.

Also, to update Angular Material in your application, run this command:

$ ng update @angular/material

If you are using a version earlier than Angular 7, follow the instructions in this official guide for the Angular upgrade.

In Conclusion…

The newest additions aren’t massive, except Ivy. But, they still are significant. So, if you are wondering whether to upgrade to Angular 8.0, the answer is yes. Since there are lesser breaking changes, your existing applications will work just fine without any alteration.

To add to this, you will be able to enjoy performance gains with differential loading and prepare your applications for Ivy. Who knows, Ivy could even become the default in Angular 9 or 10!

No comments:

Post a Comment