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
es5
) - 1 ES5 build with conditional polyfills (differential loading enabled, target is
es5
) - 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.
Configuration
- Enable differential loading by making the
tsconfig.json
target: es2015
(Javascript ES6).
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.
"Differential Loading" - A New Feature of Angular CLI v8
Suguru Inatomi ・ Apr 17 '19
- Ensure
.browserslist
includes 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.
Polyfilling
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 polyfill.ts
.
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, module
.
To compare bundle sizes, run this bash script gist by Jackub Rybinski
For more info about maintaining bundle size, check out:
Top comments (0)