DEV Community

Suguru Inatomi
Suguru Inatomi

Posted on

"Differential Loading" - A New Feature of Angular CLI v8

TL;DR

  • Angular CLI understands browsers support range from browserslist configuration.
  • If the application needs to support ES5 browsers and TypeScript target is higher than es5, the CLI automatically makes additional bundles for compatibility.
  • browserslist is the single source of truth, so es5BrowserSupport will be deprecated.

Angular CLI v8 (now in beta.15) ships new feature called "Differential Loading". It allows us to get free from considering browser compatibility of your application.

The CLI can understand browsers which the app needs to support and can make different bundles for both ES5 browsers and not.

How to use

To enable differential loading, the app must have browserslist configuration. It can be placed in package.json or browserslist file. This configuration has already been used by autoprefixer process of postcss. Apps created recently by CLI should contain it and you can find it in the project.

browserslist/browserslist

Even if you don't have it now, you can create easily with online demo. Angular CLI can look it up if browserslist file is placed at the same directory to package.json .

Preparation is over! If your tsconfig's target is out of browser range determined by browserslist , Angular CLI will separate bundles; one is for original target, and another is for ES5 browsers.

For example, let's support the latest 2 versions of Chrome and IE 11. browserslist is the following;

last 2 Chrome versions, IE 11
Enter fullscreen mode Exit fullscreen mode

And tsconfig.json is like below.

{
  "compilerOptions": {
    "target": "es2015",
        ...
  }
}
Enter fullscreen mode Exit fullscreen mode

As you may know, IE11 is an ES5 browser. So without differential loading, this application will throw errors on IE11 because of missing es2015 features like arrow functions, class or etc...

With differential loading, Angular CLI understand this problem in advance. The CLI judges whether the app has to support ES5 browsers, and check the current tsconfig's target can support them.
If they are mismatched, all bundles are separated as like main-es5.bundle.js and main-es2015.bundle.js.

Then, <script> tags for ES5 bundles are placed with nomodule attribute. It avoids loading ES5 bundles on non-ES5 browsers. As a result, on modern browsers, users will load smaller bundles just that the browser needs. It can improve loading performance.

How about es5BrowserSupport option?

Yes, Angular CLI v7.3 added a feature like differential loading but it is only for polyfills. It uses es5BrowserSupport option in angular.json .

5 Angular CLI Features You Didn't Know About

After Angular CLI v8, it will be deprecated because it is not simple to manage supporting browsers in both of browserslist for CSS and es5BrowserSupport for JavaScript. So the CLI team adopt browserslist as the single source of truth to judge whether the application needs to support ES5 browsers.

Conclusion

  • Differential loading has been landed in Angular CLI v8 beta.
  • CLI uses browserslist to judge the application needs to support ES5 browsers.
  • If tsconfig doesn't match that, CLI adds different bundles loaded only by ES5 browsers.

To try the feature, let's create an application with the following command;

$ npx @angular/cli@next new example-app
$ cd example-app
$ npm run build
Enter fullscreen mode Exit fullscreen mode

Thanks for reading!

Top comments (13)

Collapse
 
muhammedmoussa profile image
Moussa

how I can disable Differential Loading?

Collapse
 
lacolaco profile image
Suguru Inatomi

open tsconfig.json and set target: "es5". Then Angular CLI builds your code with ES5 bundle only.

Collapse
 
muhammedmoussa profile image
Moussa

I found a package browserlist, and add to package.json :
"browserlist": [
"last 2 version"
];

What the difference?

Thread Thread
 
lacolaco profile image
Suguru Inatomi • Edited
"browserlist": [
"last 2 version"
];

With this configuration, the CLI can recognize all targeted browsers are compatible ES2015. so no differential loading happens. All browsers load es2015 bundles.

If you want to align bundles to es2015, that is correct.
If you want to align bundles to es5, setting target: "es5 is correct.

Thread Thread
 
muhammedmoussa profile image
Moussa

Thank you!

Thread Thread
 
muhammedmoussa profile image
Moussa

i added :

"browserlist": [
"last 2 version"
];

to package.json and got

An unhandled exception occurred: D:\AccFlex_Cloud_Front\accflex-erb contains both browserslist and package.json with browsers
See "C:\Users\m.mousa\AppData\Local\Temp\ng-XowNha\angular-errors.log" for further details.
Thread Thread
 
michaelz profile image
Michaël Zwyssig

either use the browserlist file or the browserlist entry in package.json. You can't use both.

Collapse
 
yasuracreation profile image
yasuracreation

Hi , can i remove the defer attribute from the index.html script tags , because that attribute is not supported to theamleaf resolver ,
or else if there any configuration to organize that defer attribute like

current script is like

....................... Expected <script src="runtime.js" defer="defer">

<br> .........</p> <p>thank you </p>

Collapse
 
suriyasiva8 profile image
suriyasiva8

Hi did you found a solution for this. I'm also facing the same issue....

Collapse
 
ahasall profile image
Amadou Sall

Very nice and well written article Sugury.

Collapse
 
jovidecroock profile image
Jovi De Croock

Nice article, is the Safari 10.1 bug covered in the module-nomodule approach here? gist.github.com/samthor/64b114e4a4...

If so, how is double download in IE11 and triple download in Edge prevented?

Collapse
 
lacolaco profile image
Suguru Inatomi

github.com/angular/angular-cli/blo...

Safari's problem is covered by CLI. I don't know about Edge.

Collapse
 
tasneemghorayeb profile image
:*

Thank you for the article. I was worried about changing the target and supporting less browsers. Although I can't find any browser that doesn't support es2015 anymore.(other than ie). But still a relief.

My other( perhaps rather primitive) question would be, What is the difference between the browserList and polyfills ?, they seem to be doing the same thing..