Angular 8 : Ivy-Preview, Service Worker and Differential Loading - these are the new features

Angular 8 comes with a pre-release version of Ivy, service worker support, differential loading and other small rounding. Now the new major version is available. What changes for developers? Here are the new features at a glance.

At the end of May 2019 Angular 8 was released. As planned, there were no surprises: The update of the framework and CLI is straightforward with ng update . The new features are a welcome addition, true to the motto: “evolution instead of revolution”.

In this article I discuss the most important changes of Angular 8 and the corresponding Angular CLI 8. The examples used are available on GitHub.

Taste of Angular 8 : Ivy

The next big thing the Angular world is waiting for is Ivy. This is a new Angular compiler and a new rendering pipeline. Angular 8 Ivy has the potential to generate much smaller bundles, making incremental compilation easier and the foundation for future innovation in the Angular environment.

Since some parts are exchanged here in the substructure of Angular, the Angular team pays particular attention to compatibility with previous Angular versions: Existing applications should work exactly the same way as before, and in the best case with noticeably smaller bundles after switching to Ivy. This is not quite altruistic, especially since Google officially over 600 applications based on Angular – the “dark figure,” it is rumored, is much higher.

With Angular 8, Ivy is now available for testing in a pre-release version. The goal of this version is to get early feedback. That’s why the Angular team also recommends not putting on Ivy for productive applications, but on the classic View Engine ( image 1 ).

Angular 8 is here: Ivy-Preview

Thanks to differential loading (see below), the bundle sizes can be optimized immediately.

As mentioned by Brad Green, the technical director behind the Angular team at Google, at the ngconf 2019, Ivy, in compatibility mode with Differential Loading, will enable a noticeable improvement in bundle sizes. Those looking for a thrill can try the future API from Ivy today. Especially this mode has a considerable potential for optimization. However, this API is currently classified as private, as evidenced by the fact that its classes and functions begin with the special character ɵ.

Anyone who wants to try Ivy today can create a new project using the –enable-ivy switch:

ng new ivy-project –enable-ivy

This causes the CLI to store the following configuration entry in tsconfig.app.json :

“angularCompilerOptions”: { “enableIvy”: true }

This entry can also be made manually after updating to Angular 8 to test an existing application with Ivy.

To run the application in debug mode, it is recommended to set to AOT:

ng serve –aot

It is also worth taking a look at the size of the application built with ng build . With Angular 9 Ivy is finally to be activated by default for the first time. Until then, the Angular team would like to ensure the compatibility with older versions by further measures.

Web Worker

JavaScript is by definition single-threaded. Because of this, it is also common for longer tasks, such as fetching data, to be asynchronous. Of course this does not help with complex calculations. However, these are becoming increasingly common in rich JavaScript solutions. That’s why just about all browsers support web workers. These are scripts that the browser executes in its own thread. The communication with the thread in the browser tab is done by sending messages.

While web workers are not related to Angular per se, they should be considered during build. The goal is to provide a bundle per web worker. This is exactly what the new Angular CLI does.

To illustrate this new feature, a JavaScript implementation of the so-called Damen problem , also known as the Queens problem, is used. The idea behind it is to place a queen on a chessboard per row, without being able to beat each other ( img. 2 ). This means there must not be any other ladies in the same row, column or diagonal.

chessboard

An algorithm that determines all possible solutions on a chessboard is considered computationally intensive. While the calculation for a conventional checkerboard with eight rows and eight columns is relatively quick, bumps from 12 x 12 fields to normal limits. The current record lies in determining the solutions for a board with 27 x 27 fields. For this purpose Russian supercomputers were used.

To outsource such a calculation, you first have to generate a web worker using the Angular CLI:

ng generate worker n-queens

This statement not only creates a file for the worker, but also the configuration files needed for the build, as well as entries in existing files. If a component of the same name with the usual extension .component.ts exists in the same folder, the CLI even enriches this component with code that communicates with the Web Worker.

The worker itself consists of just one event listener for the message event (Listing 1).

import nQueens from ‘./n-queens’;
addEventListener(‘message’, ({ data }) => {
const result = nQueens(data.count);
postMessage(result, undefined);
});

This event occurs when the main thread sends a message to the worker. The parameter contains the information sent by the main thread. In the case under consideration, they are limited to the count property, which announces the checkerboard size. After the calculation with the nQueens function not shown here for reasons of space, the event listener sends the result back to the main thread with postMessage . This causes the browser to trigger a message event there.

To interact with this worker script, the working component uses the class Worker (Listing 2).

\\ const count = parseInt(this.count, 10);

\\ const worker = new Worker(‘../logic/n-queens.worker’, {
\\ type: ‘module’ // Worker uses EcmaScript modules
\\ });

\\ worker.postMessage({count});

\\ worker.addEventListener(‘message’, (event) => {
// tslint:disable-next-line: no-console
\\ console.debug(‘worker result’, event.data);

// Update chessboard
\\ this.processResult(event.data);
\\ });

With postMessage, the component sends a message with the desired playing field size to the worker, thus triggering the calculation there. She receives the result via the message event.

Subsequently, the CLI takes care of the correct translation and bundling of the worker scripts. The TypeScript compiler triggered by this recognizes them at the extension .worker.ts , which is registered in the file generated by ng generate worker tsconfig.worker.json . So that the CLI does not take these files into consideration when translating and bundling the main application, ng generate worker also includes the same file pattern in the exclude section of tsconfig.app.json.

The entire implementation is in the author’s sample collection . By way of illustration, the example found there enables the problem of the lady to be solved both in the main thread and in a web worker. For example, if you request a solution for a 12 x 12 chessboard, you find that the former freezes the UI, while the background execution in the worker does not restrict usability during the calculation.

Differential loading

So far, it has been common practice to compile applications into the good old ECMAScript 5, as this “JavaScript of our Fathers” runs as well as anywhere these days. Thus, both the IE 11 and the Web Crawler, which is behind the Google search engine, run the program code.

However, the newer ECMAScript 2015 and its subsequent versions are more efficient: these versions allow for more compact bundles and the browser can also interpret them more efficiently. Unfortunately, since ECMAScript 5 has retreated to the lowest common denominator, modern browsers could not use these advantages.

Now that’s over: The CLI brings from version 8 with a feature called Differential Loading. The idea of ​​this is to provide two sets of bundles: some based on ECMAScript 5 and serving older browsers, the others based on a recent ECMAScript version, e.g. Eg ECMAScript 2015 and offer the advantages mentioned to modern browsers.

There is not much that needs to be done to enable differential loading: it is only necessary to specify an upper and a lower bound for the ECMAScript versions to be supported. The upper bound must be entered in tsconfig.json

“target”: “es2015”

The lower bound is defined by a browser list. This is a file that identifies a set of browsers to support through certain criteria, such as market penetration. These are z. For example, in the file browserslist , which now creates the CLI when generating a new project in the project root:

> 0.5%
last 2 versions
Firefox ESR
not dead
IE 9-11

In the case in question, the browserlist refers among other things to IE 9-11 on ECMAScript 5 browsers. Thus, the CLI sets the lower bound to this version.

Now, when the CLI gets the instruction to build ( ng build ), compile and bundle operations will take place for both versions.
The disadvantage of this process is also obvious here: The time required for the build process is doubled.

The individual browsers can now decide which version of the bundles they want to load. Add the script references in the index.html additions: Those referring to ECMAScript 5 bundles receive the addition nomodule . This prevents browser, the ECMAScript modules and thus min. Master ECMAScript 2015, ignore the reference. The ECMAScrupt 2015 + bundles, on the other hand, integrate the CLI via type = “module” . Older browsers ignore these script tags:

< script src=”main-es2015.js” type=”module” >< / script >
< script src=”main-es5.js” nomodule>< / script >

Unlike ng build , all other CLI commands only use (!) The upper bound. In the considered case, the ECMAScript 2015. This is done, among other things, for reasons of efficiency: Especially when debugging or testing developers want to see a result as quickly as possible, without constantly having to wait for a second build.

Conclusion

Once again, the Angular team kept their word: migrating to the new Angular version is easy and easy. Instead, there are some very nice rounds that make working with the Google SPA framework even more convenient. Differential Loading creates an awareness that the bundle sizes can be further optimized if you do not support old browsers, or at least with separate bundles. Web Worker support shows that more and more computationally intensive tasks are migrating to the browser. Enthusiasts can now also make first attempts with Ivy.

LEAVE A REPLY

Please enter your comment!
Please enter your name here