- jen chan
This post discusses ways to support “legacy” browsers in terms of IE 11, and tuning Angular to support differential loading.
Before we changing build configs, there are 4 different scenarios you could end up with:
- 1 ES5 build (differential loading disabled, target is
- 1 ES5 build with conditional polyfills (differential loading enabled, target is
- 1 ES2015 build (differential loading disabled, target is es2015), which won't support IE 11
- 2 builds with conditional polyfills (differential loading enabled, target as
es2015) This doc explains how to accomplish #4.
- Enable differential loading by making the
Little has changed from Angular 8 other than retiring of the
es5BrowserSupport tag. Follow the steps below for adding
tsconfig.app.json with configurations targetting
es5 export in your build and serve (on local dev) your app for legacy browsers.
.browserslistincludes all versions of browsers the project intends to support. This file refers to the compile configuration tool browserslist. Each statement in browserslist is read as a query string, which is runs against Can I Use data on support of various language features. Their github has great explanations of how to write accurate queries.
On build, Browserslist determines which browsers the app supports, and compiles JS files for ES5 (to support legacy browsers) and ES6+ supporting modern browsers.
Check caniuse.com for various es6 expressions and update
polyfills.ts file with the necessary polyfills. It would be good to take stock of what kind of modern development features you're using. For example, IE 11 doesn't support flex grid, as well as ES6-ES11 features such as
.includes(), promises, for-of or
Object.keys() iteration, and optional chaining.
Angular’s “Browser Support” docs suggest
classlist, all the
core-js elements and
web-animations if you are using Angular Material, but in the interest of keeping our legacy browsers' bundle size small, we should only polyfill for classlist and the ES6, ES7-11 features that our projects use. Make sure you
npm install the polyfill package before you import it into
In tandem with the
polyfills.ts, step tells Angular to export a bundle for modern browsers, and a bundle for legacy browsers.
How Do We Know It Worked?
After you run
ng build --prod and check your
dist/ or project folder, you’ll notice your
index.html contains something like the following:
<script src="fancyModernBundle-es2015.js" type="module"></script> <script src="legacyBundle-es5.js" nomodule></script>
When you run the project locally or visit the deployed development version, open up the network tab of the developer tools and refresh the page. For modern browsers, you should see only the scripts that include
-es2015 in the name. For IE 11, you would only see scripts that include
-es5 in the name, and it will ignore any script tags with the type,
To compare bundle sizes, run this bash script gist by Jackub Rybinski
For more info about maintaining bundle size, check out: Suguru Inatomi, "Differential Loading" - A New Feature of Angular CLI v8, Apr 17, 2019
[Pro Tip] How to analyze your Angular bundle, Sep 13, 2019