{"id":474,"date":"2021-03-25T17:18:07","date_gmt":"2021-03-25T17:18:07","guid":{"rendered":"https:\/\/ccbill.com\/kb\/?p=474"},"modified":"2024-09-13T15:05:43","modified_gmt":"2024-09-13T15:05:43","slug":"differential-loading-angular","status":"publish","type":"post","link":"https:\/\/ccbill.com\/kb\/differential-loading-angular","title":{"rendered":"Differential Loading in Angular 8"},"content":{"rendered":"<p class=\"h3\">Introduction<\/p>\n\n\n<p>The size and complexity of web applications are constantly growing each year. We are constructing sophisticated tools, which require more JavaScript libraries to be shipped to clients' browsers. In 2020 the median amount of JavaScript included on a page <a rel=\"noreferrer noopener nofollow\" href=\"https:\/\/httparchive.org\/reports\/state-of-javascript#bytesJs\" target=\"_blank\">topped 440KBs<\/a>. This trend continuously adds on to the total weight of the page and is affecting its performance, both load time and runtime. <\/p>\n\n\n\n<p>Furthermore, the execution environment of JavaScript is constantly changing. Browsers are shipping new APIs, adding support for new JavaScript syntax, and new standards are emerging. As a developer, you\u2019d like to leverage those to improve user experience, but how to do that if you need the website to work well on legacy browsers as well? <\/p>\n\n\n\n<p>The answer has traditionally been <em>polyfilling<\/em> and <em>transpilation<\/em>. We shall touch briefly on these approaches later in this article. The issue, however, is that these approaches add even more JavaScript into the application.<\/p>\n\n\n\n<p><strong>In this article, we explain why and how differential loading is used to support legacy browsers without bloating the JavaScript shipped to modern browsers.<\/strong><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"800\" height=\"400\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png\" alt=\"Understanding differential loading in Angular 8 and how to manually set it up.\" class=\"wp-image-475\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8-300x150.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8-768x384.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">What is Differential Loading Used For?<\/h2>\n\n\n\n<p>Differential loading ensures that the most modern browsers are not bloated with unnecessary polyfills and transpiled code targeting legacy browsers, while legacy browsers receive the full package to ensure compatibility.<\/p>\n\n\n\n<p>Differential loading also resolves the need for unnecessary transpilation down to ECMAScript 5 and redundant polyfills inclusion for modern browsers that do not require it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">JavaScript Language and Browser APIs Evolution<\/h2>\n\n\n\n<p>JavaScript and browsers have come a long way, and the ecosystem is constantly changing. Let us take a look at the main dimensions of this change, which are the main drivers for the technique in subject.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">JavaScript Syntax Evolution and Transpilation<\/h3>\n\n\n\n<p>JavaScript is an implementation of <a rel=\"noreferrer noopener nofollow\" href=\"https:\/\/www.ecma-international.org\/ecma-262\/\" target=\"_blank\"><em>ECMAScript<\/em><\/a> specification as well as <a href=\"https:\/\/phoenixnap.com\/kb\/install-node-js-npm-on-windows\" target=\"_blank\" rel=\"noreferrer noopener\">Node.js<\/a>. In the past, <em>ECMAScript<\/em> version releases were infrequent, to the extent that we needed to wait years for the release of ES6. The body governing this process is TC39, and, thankfully, they adopted a more incremental approach, which results in much more frequent version releases.<\/p>\n\n\n\n<p>Some of the most notable features introduced by ES6 were classes, template literals, arrow functions, and many more. You can refer to this <a href=\"https:\/\/compat-table.github.io\/compat-table\/es6\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">compatibility table<\/a> for reference and more details on the ES6 scope. All of these features are widely available nowadays in modern browsers. Since then, we have had multiple yearly releases, including more improvements to the language like <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Learn\/JavaScript\/Asynchronous\/Async_await\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">async\/await<\/a> or recently <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/Optional_chaining\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">the optional chaining operator<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"105\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/async-await-dynamic-imports-angular.png\" alt=\"An example of the async\/await feature.\" class=\"wp-image-477\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/async-await-dynamic-imports-angular.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/async-await-dynamic-imports-angular-300x39.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/async-await-dynamic-imports-angular-768x101.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Top level async\/await with dynamic imports.<\/figcaption><\/figure>\n\n\n\n<p>The new language features go through multiple approval stages, which can be monitored on the <em>TC39<\/em> official <a href=\"https:\/\/github.com\/tc39\/proposals\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">GitHub profile<\/a>. <\/p>\n\n\n\n<p>Imagine you wanted to leverage modern language constructs. If it weren't for transpilation, you would need to wait years for browsers to support it fully. Instead, we can transpile modern language syntax into constructions available to legacy browsers and thus instantly start leveraging new capabilities in our projects. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-vivid-cyan-blue-color has-css-opacity has-vivid-cyan-blue-background-color has-background is-style-wide\"\/>\n\n\n\n<p><strong>Note<\/strong>: One has to bear in mind that not all language constructs can be transpiled.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-vivid-cyan-blue-color has-css-opacity has-vivid-cyan-blue-background-color has-background is-style-wide\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Browser APIs Evolution and Polyfills<\/h3>\n\n\n\n<p>The body governing the evolution of browser APIs is W3C. One can refer to the same matrix as for <em>ECMAScript<\/em> to see what new methods or properties are added to the classes provided globally in the browsers. On top of that there is a whole new range of features, like <a href=\"https:\/\/developers.google.com\/web\/fundamentals\/primers\/service-workers\" target=\"_blank\" rel=\"noreferrer noopener\">the service workers<\/a>, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/WebSockets_API\" target=\"_blank\" rel=\"noreferrer noopener\">WebSocket API<\/a>, or <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/MutationObserver\" target=\"_blank\" rel=\"noreferrer noopener\">MutationObserver<\/a>.<\/p>\n\n\n\n<p>Some of those can be polyfilled. A polyfill is a JavaScript library that adds or patches a functionality in legacy browsers. For instance, <em>MutationObserver<\/em> can be polyfilled, while <em>WebSocket<\/em> connection or <em>Service Worker<\/em> cannot.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">JavaScript Dependency Management<\/h3>\n\n\n\n<p>For a very long time, JavaScript had no mechanism of dependency handling. One would need to manually ensure that all required dependencies for their website or web app were correctly included and ordered. <\/p>\n\n\n\n<p>This was turning quickly into a maintenance nightmare as the complexity and amount of dependencies grew. That approach was clearly not scalable and several approaches were proposed to fill in this gap before the official standard emerged.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">RequireJS<\/h4>\n\n\n\n<p>One module loading approach is the <em>Asynchronous Module Definition (<\/em><a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Asynchronous_module_definition\" target=\"_blank\">AMD<\/a>). <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Asynchronous_module_definition\" target=\"_blank\">RequireJS<\/a> is an example implementation of this specification. It is a first attempt to solve the problem of missing dependency-handling functionality in browsers. <\/p>\n\n\n\n<p>Its asynchronous nature means that code requiring dependencies is executed as part of a callback function which is invoked only after said dependencies are made available.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"128\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/amd-syntax-example-angular.png\" alt=\"An example of the AMD syntax structure.\" class=\"wp-image-479\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/amd-syntax-example-angular.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/amd-syntax-example-angular-300x48.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/amd-syntax-example-angular-768x123.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">AMD Syntax Example<\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">CommonJS<\/h4>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"http:\/\/www.commonjs.org\/specs\/modules\/1.0\/\" target=\"_blank\">CommonJS<\/a> was developed primarily for Node.js and, as opposed to <em>AMD<\/em>, it is a synchronous module loading mechanism. It is possible to leverage it on the browser side using build tools like <a rel=\"noreferrer noopener\" href=\"http:\/\/browserify.org\/\" target=\"_blank\">browserify<\/a> or <a rel=\"noreferrer noopener\" href=\"https:\/\/webpack.js.org\/concepts\/modules\/\" target=\"_blank\">webpack<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"800\" height=\"130\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/commonjs-example-syntax-angular-8.png\" alt=\"An example of the CommonJS syntax.\" class=\"wp-image-480\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/commonjs-example-syntax-angular-8.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/commonjs-example-syntax-angular-8-300x49.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/commonjs-example-syntax-angular-8-768x125.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">CommonJS Syntax Example<\/figcaption><\/figure><\/div>\n\n\n<h4 class=\"wp-block-heading\">Universal Module Definition<\/h4>\n\n\n\n<p>There was a mixture in the ecosystem, with some packages leveraging the <em><em>Asynchronous Module Definition<\/em><\/em> and some the <em><em>Synchronous Module<\/em><\/em> loading mechanism. Hence, the <em>Universal Module Definition<\/em> (<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/umdjs\/umd\" target=\"_blank\">UMD<\/a><ins>)<\/ins> was created.<\/p>\n\n\n\n<p>As per its name, Universal Module Definition is meant to be a universal syntax, working on both the server and client side. It detects what setup it is run on (<em>AMD<\/em> or <em>CommonJS<\/em>) and executes module handling accordingly.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"376\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/umd-definition-example.png\" alt=\"An example of the UMD syntax.\" class=\"wp-image-482\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/umd-definition-example.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/umd-definition-example-300x141.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/umd-definition-example-768x361.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">UMD definition retrieved from<a href=\"https:\/\/github.com\/umdjs\/umd\" target=\"_blank\" rel=\"noreferrer noopener\"> umdjs\/umd<\/a><\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">ECMAScript Modules<\/h4>\n\n\n\n<p>All this brought us to the ECMAScript Modules (<a rel=\"noreferrer noopener\" href=\"https:\/\/v8.dev\/features\/modules\" target=\"_blank\">ESM<\/a>), a language-level standardized way to handle modules, available in both Node.js and client side in modern browsers, and leveraged in differential loading.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"800\" height=\"132\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/esm-syntax-example-angular-8.png\" alt=\"An example of the ESM syntax.\" class=\"wp-image-483\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/esm-syntax-example-angular-8.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/esm-syntax-example-angular-8-300x50.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/esm-syntax-example-angular-8-768x127.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">ESM Syntax Example<\/figcaption><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Transpilation<\/h3>\n\n\n\n<p>Transpilation is the process of compilation of JavaScript source code based on older <em>ECMAScript<\/em> specification.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"342\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/transpilation-es5-syntax-1.png\" alt=\"Transilation to ES5 example.\" class=\"wp-image-486\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/transpilation-es5-syntax-1.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/transpilation-es5-syntax-1-300x128.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/transpilation-es5-syntax-1-768x328.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Modern Class Syntax Transpiled to ES5<\/figcaption><\/figure>\n\n\n\n<p>In the example above, you can see ES6 <em>class <\/em>definition using modern syntax, and, on the right, the transpiled version leveraging a closure and a function constructor.<\/p>\n\n\n\n<p>There are a number of tools to handle this process, the two most popular ones being <a rel=\"noreferrer noopener\" href=\"https:\/\/www.typescriptlang.org\/\" target=\"_blank\"><em>TypeScript<\/em><\/a> and <a rel=\"noreferrer noopener\" href=\"https:\/\/babeljs.io\/\" target=\"_blank\"><em>babel<\/em><\/a>. Transpilation is usually a build step in your application. In case of <em>differential loading<\/em>, the result would be two versions of the JavaScript codebase \u2013 one transpiled for the use of legacy browsers and one original meant for modern browsers.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Polyfills<\/h3>\n\n\n\n<p>On the other hand, polyfills are meant to provide an implementation or a patch for a standard browser API that is not available yet, for example <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Object\/keys\" target=\"_blank\">Object.keys<\/a> or <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/String\/padStart\" target=\"_blank\">String.prototype.padStart<\/a>.<\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/zloirock\/core-js\" target=\"_blank\">Core-js<\/a> is an example of a popular set of polyfills<ins>,<\/ins> being almost a one-stop shop for supporting recent APIs in legacy browsers. <\/p>\n\n\n\n<p>The common denominator for functionalities that can be polyfilled is the possibility of imitating said functionality with existing APIs and JavaScript language features.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How Does Differential Loading Work?<\/h2>\n\n\n\n<p>The base for differential loading is a newly introduced <a rel=\"noreferrer noopener\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Element\/script\" target=\"_blank\"><em>module<\/em> type for HTML <em>script <\/em>tags<\/a>, as well as the new <em><strong>nomodule <\/strong><\/em>attribute available for script tags. The concept is pretty easy and goes as follows:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table class=\"has-fixed-layout\"><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><img decoding=\"async\" width=\"103\" height=\"96\" class=\"wp-image-490\" style=\"width: 103px;\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/chrome-logo-1.png\" alt=\"\"><\/td><td class=\"has-text-align-center\" data-align=\"center\"><img decoding=\"async\" width=\"103\" height=\"79\" class=\"wp-image-491\" style=\"width: 103px;\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/explorer-logo-1.png\" alt=\"\"><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Modern browsers recognize both <em>module<\/em> typescript and <em>nomodule<\/em> attribute, thus are loading and processing the <em>module<\/em> only.<\/td><td class=\"has-text-align-center\" data-align=\"center\">Legacy browsers do not know how to handle <em>module<\/em> type <em>script<\/em> tags and thus ignoring them completely, while using the one marked with the attribute <em>nomodule<\/em> as it is the standard <em>text\/javascript <\/em>type.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" width=\"800\" height=\"60\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-javascript-two-versions.png\" alt=\"Differential Loading with two versions of app's JavaScript.\" class=\"wp-image-492\" style=\"width:580px;height:43px\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-javascript-two-versions.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-javascript-two-versions-300x23.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-javascript-two-versions-768x58.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Differential Loading Using Two Versions of the App\u2019s JavaScript<\/figcaption><\/figure><\/div>\n\n\n<p>In the snippet above, you can see that Chrome downloads and processes <em>esm.bundle.mjs<\/em> file since it is included using the <em>script <\/em>tag of type <em>module<\/em>. Chrome ignores the <em>es5.bundle.js <\/em>since the <em>script <\/em>tag is marked as <em>nomodule<\/em>. IE9, on the other hand, does the opposite since it is not able to process <em>script <\/em>tags of type <em>module<\/em>, and the other is perceived as a regular <em>script<\/em> tag. <\/p>\n\n\n\n<p>Should you wish to read more about the nature of <em>ECMAScriptmodules <\/em>you can refer to this <a href=\"https:\/\/v8.dev\/features\/modules\" target=\"_blank\" rel=\"noreferrer noopener\">succinct write-up<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Differential Loading in Angular<\/h2>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/angular.io\/guide\/deployment#differential-loading\" target=\"_blank\">Differential loading<\/a> is handled by the <a rel=\"noreferrer noopener\" href=\"https:\/\/cli.angular.io\/\" target=\"_blank\">Angular Client<\/a> automatically, based on the <em>browserlist<\/em> target for your application. As of <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.angular.io\/version-10-of-angular-now-available-78960babd41\" target=\"_blank\">Angular 10<\/a>, it assumes one is targeting only the modern subset of browsers, thus disabling ES5 compilation and differential loading altogether. However, upon the update of the supported browsers list, this behavior is amended based on the list provided.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"800\" height=\"377\" src=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/application-bundle-set-angular-client.png\" alt=\"Two bundle sets provided by Angular Client.\" class=\"wp-image-495\" srcset=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/application-bundle-set-angular-client.png 800w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/application-bundle-set-angular-client-300x141.png 300w, https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/application-bundle-set-angular-client-768x362.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Two Application Bundle Sets Provided by Angular Client<\/figcaption><\/figure>\n\n\n\n<p>As seen in the snippet above, <em>Angular Client<\/em> generated two sets of bundles for our application as required for <em>differential loading<\/em> \u2013 a set of ES2015+ and ES5 resources. It also amended the <em>index.html <\/em>file in the background with the script tags required to load up and bootstrap the application. <\/p>\n\n\n\n<p>Looking at the generated files, the saving in terms of payload size is clearly visible. For instance, <em>common-es5 <\/em>bundle (legacy browsers) weighs <strong>15KB, <\/strong>while<em> common-es2015 bundle <\/em>(modern browsers) weighs<strong> 13.1KB<\/strong>. The difference is even more significant when we look at polyfills \u2013 ES5 (legacy browsers) is almost <strong>70KB<\/strong>, and ES2015 (modern browsers) is only <strong>130 bytes<\/strong>!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Manually Setup of Differential Loading<\/h2>\n\n\n\n<p>To have <em>differential loading<\/em> set up, one has to have a build outputting two distinct bundle types. One build generating an ES5 bundle and another generating the modern one, ES2015+. <\/p>\n\n\n\n<p>It is really easy to switch between compilation targets in both <em>Babel<\/em> and <em>Typescript<\/em>. It is enough to run your transpiler via a bundler of your choice (i.e., <a rel=\"noreferrer noopener\" href=\"https:\/\/webpack.js.org\/\" target=\"_blank\">webpack<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/rollupjs.org\/guide\/en\/\" target=\"_blank\">rollup<\/a>, or <a rel=\"noreferrer noopener\" href=\"https:\/\/parceljs.org\/\" target=\"_blank\">parcel<\/a>) twice, providing a different transpiler configuration file for it to digest. For further details, see example .babelrc configuration file below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n    &quot;presets&quot;: &#091;\n        &#091;&quot;env&quot;, {\n            &quot;targets&quot;: {\n                &quot;browsers&quot;: &#091;&quot;last 2 versions&quot;] \/\/ target determined from browsers list\n            }\n        }]\n    ],\n    &quot;plugins&quot;: &#091;&quot;external-helpers&quot;]\n}<\/code><\/pre>\n\n\n\n<p>And this example TypeScript configuration file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  &quot;compileOnSave&quot;: false,\n  &quot;compilerOptions&quot;: {\n    &quot;baseUrl&quot;: &quot;.\/&quot;,\n    &quot;outDir&quot;: &quot;.\/dist\/out-tsc&quot;,\n    &quot;sourceMap&quot;: true,\n    &quot;module&quot;: &quot;esnext&quot;,\n    &quot;moduleResolution&quot;: &quot;node&quot;,\n    &quot;importHelpers&quot;: true,\n    &quot;target&quot;: &quot;es2015&quot;, \/\/ target ES version\n    &quot;typeRoots&quot;: &#091;\n      &quot;node_modules\/@types&quot;\n    ],\n    &quot;lib&quot;: &#091;\n      &quot;es2018&quot;,\n      &quot;dom&quot;\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<p>All those steps can be composed into a single command using <em>npm<\/em> or <em>yarn<\/em> scripts.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  &quot;name&quot;: &quot;the-portal&quot;,\n  &quot;version&quot;: &quot;0.0.1&quot;,\n  &quot;scripts&quot;: {\n     &quot;build:diff&quot;: &quot;yarn webpack:es5 &amp;&amp; yarn webpack:es2015&quot;,\n     &quot;webpack:es5&quot;: &quot;webpack --config config\/webpack.es5.js --mode production&quot;,\n     &quot;webpack:es2015&quot;: &quot;webpack --config config\/webpack.es2015.js --mode production&quot;\n  },\n \u2026\n}<\/code><\/pre>\n\n\n\n<p>The example above invokes the <em>build:diff <\/em>script, which in turn would call <em>webpack <\/em>twice to produce two versions of the application, according to the configuration files it was fed. Once this is done, all you have to do is include the produced bundles in your <em>index.html<\/em> file using the technique described above.<\/p>\n\n\n<p class=\"h3\">Conclusion<\/p>\n\n\n<p><em>Differential loading<\/em> is an interesting performance optimization one can apply in every web application. It not only yields a reduction in the weight of the application and thus reduces the initial load time but also limits the amount of processing the browser has to do on loaded JavaScript. <\/p>\n\n\n\n<p>Differential loading enables potential runtime performance improvements in modern browsers thanks to the fact they leverage native implementations of APIs that would have been otherwise polyfilled with custom, slower JavaScript. The only price to be paid is a slightly more complex build setup with application builds taking longer.<\/p>\n\n\n\n<p>Differential loading is definitely worth looking into as the setup is not complicated and, in some cases, like for Angular, available out of the box. The concept is easy to grasp and thus does not add much to the overall setup complexity, giving measurable returns in the form of performance and UX improvements.<\/p>\n\n\n\n<p>Setting it up for your application will not do any damage, but the gains from it highly depend on the browsers list that your application has to support as well as APIs and JavaScript syntax used in your codebase. Differential loading is always beneficial but yields greatest savings when the app leverages the latest JavaScript language features and has a wide spectrum of browsers to support.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article provides a comprehensive overview of differential loading. It also contains practical advice on how to set up differential loading in Angular.<\/p>\n","protected":false},"author":11,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[14],"tags":[],"class_list":["post-474","post","type-post","status-publish","format-standard","hentry","category-web-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Differential Loading in Angular 8 {What It Is and How to Set Up}<\/title>\n<meta name=\"description\" content=\"Learn how to use differential loading in Angular expertly. Optimize the performance of your web applications for a wide array of browsers.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ccbill.com\/kb\/differential-loading-angular\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Differential Loading in Angular 8 {What It Is and How to Set Up}\" \/>\n<meta property=\"og:description\" content=\"Learn how to use differential loading in Angular expertly. Optimize the performance of your web applications for a wide array of browsers.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ccbill.com\/kb\/differential-loading-angular\" \/>\n<meta property=\"og:site_name\" content=\"CCBill Knowledge Base\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ccbillBIZ\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-25T17:18:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-13T15:05:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png\" \/>\n<meta name=\"author\" content=\"Artur Banas\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CCBillBIZ\" \/>\n<meta name=\"twitter:site\" content=\"@CCBillBIZ\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Artur Banas\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular#article\",\"isPartOf\":{\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular\"},\"author\":{\"name\":\"Artur Banas\",\"@id\":\"https:\/\/ccbill.com\/kb\/#\/schema\/person\/054b4aa0928b00dbb64b830a2be8da82\"},\"headline\":\"Differential Loading in Angular 8\",\"datePublished\":\"2021-03-25T17:18:07+00:00\",\"dateModified\":\"2024-09-13T15:05:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular\"},\"wordCount\":1818,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/ccbill.com\/kb\/#organization\"},\"image\":{\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png\",\"articleSection\":[\"Web Development\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/ccbill.com\/kb\/differential-loading-angular#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular\",\"url\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular\",\"name\":\"Differential Loading in Angular 8 {What It Is and How to Set Up}\",\"isPartOf\":{\"@id\":\"https:\/\/ccbill.com\/kb\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage\"},\"image\":{\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage\"},\"thumbnailUrl\":\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png\",\"datePublished\":\"2021-03-25T17:18:07+00:00\",\"dateModified\":\"2024-09-13T15:05:43+00:00\",\"description\":\"Learn how to use differential loading in Angular expertly. Optimize the performance of your web applications for a wide array of browsers.\",\"breadcrumb\":{\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ccbill.com\/kb\/differential-loading-angular\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage\",\"url\":\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png\",\"contentUrl\":\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png\",\"width\":800,\"height\":400,\"caption\":\"Popluar browser logos and tutorial title.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ccbill.com\/kb\/differential-loading-angular#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"KB Home\",\"item\":\"https:\/\/ccbill.com\/kb\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Development\",\"item\":\"https:\/\/ccbill.com\/kb\/category\/web-development\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Differential Loading in Angular 8\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ccbill.com\/kb\/#website\",\"url\":\"https:\/\/ccbill.com\/kb\/\",\"name\":\"CCBill Knowledge Base\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/ccbill.com\/kb\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ccbill.com\/kb\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ccbill.com\/kb\/#organization\",\"name\":\"CCBill\",\"url\":\"https:\/\/ccbill.com\/kb\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ccbill.com\/kb\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/ccbill-logo.png\",\"contentUrl\":\"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/ccbill-logo.png\",\"width\":160,\"height\":70,\"caption\":\"CCBill\"},\"image\":{\"@id\":\"https:\/\/ccbill.com\/kb\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/ccbillBIZ\/\",\"https:\/\/x.com\/CCBillBIZ\",\"https:\/\/www.linkedin.com\/company\/ccbill\",\"https:\/\/www.youtube.com\/c\/CCBillBiz\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/ccbill.com\/kb\/#\/schema\/person\/054b4aa0928b00dbb64b830a2be8da82\",\"name\":\"Artur Banas\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ccbill.com\/kb\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/278e436cdf4785ca9f2835fc27f5bd094bdce4f1dba43323b98815b361785009?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/278e436cdf4785ca9f2835fc27f5bd094bdce4f1dba43323b98815b361785009?s=96&d=mm&r=g\",\"caption\":\"Artur Banas\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Differential Loading in Angular 8 {What It Is and How to Set Up}","description":"Learn how to use differential loading in Angular expertly. Optimize the performance of your web applications for a wide array of browsers.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ccbill.com\/kb\/differential-loading-angular","og_locale":"en_US","og_type":"article","og_title":"Differential Loading in Angular 8 {What It Is and How to Set Up}","og_description":"Learn how to use differential loading in Angular expertly. Optimize the performance of your web applications for a wide array of browsers.","og_url":"https:\/\/ccbill.com\/kb\/differential-loading-angular","og_site_name":"CCBill Knowledge Base","article_publisher":"https:\/\/www.facebook.com\/ccbillBIZ\/","article_published_time":"2021-03-25T17:18:07+00:00","article_modified_time":"2024-09-13T15:05:43+00:00","og_image":[{"url":"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png","type":"","width":"","height":""}],"author":"Artur Banas","twitter_card":"summary_large_image","twitter_creator":"@CCBillBIZ","twitter_site":"@CCBillBIZ","twitter_misc":{"Written by":"Artur Banas","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular#article","isPartOf":{"@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular"},"author":{"name":"Artur Banas","@id":"https:\/\/ccbill.com\/kb\/#\/schema\/person\/054b4aa0928b00dbb64b830a2be8da82"},"headline":"Differential Loading in Angular 8","datePublished":"2021-03-25T17:18:07+00:00","dateModified":"2024-09-13T15:05:43+00:00","mainEntityOfPage":{"@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular"},"wordCount":1818,"commentCount":0,"publisher":{"@id":"https:\/\/ccbill.com\/kb\/#organization"},"image":{"@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage"},"thumbnailUrl":"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png","articleSection":["Web Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ccbill.com\/kb\/differential-loading-angular#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular","url":"https:\/\/ccbill.com\/kb\/differential-loading-angular","name":"Differential Loading in Angular 8 {What It Is and How to Set Up}","isPartOf":{"@id":"https:\/\/ccbill.com\/kb\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage"},"image":{"@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage"},"thumbnailUrl":"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png","datePublished":"2021-03-25T17:18:07+00:00","dateModified":"2024-09-13T15:05:43+00:00","description":"Learn how to use differential loading in Angular expertly. Optimize the performance of your web applications for a wide array of browsers.","breadcrumb":{"@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ccbill.com\/kb\/differential-loading-angular"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular#primaryimage","url":"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png","contentUrl":"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/differential-loading-angular-8.png","width":800,"height":400,"caption":"Popluar browser logos and tutorial title."},{"@type":"BreadcrumbList","@id":"https:\/\/ccbill.com\/kb\/differential-loading-angular#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"KB Home","item":"https:\/\/ccbill.com\/kb\/"},{"@type":"ListItem","position":2,"name":"Web Development","item":"https:\/\/ccbill.com\/kb\/category\/web-development"},{"@type":"ListItem","position":3,"name":"Differential Loading in Angular 8"}]},{"@type":"WebSite","@id":"https:\/\/ccbill.com\/kb\/#website","url":"https:\/\/ccbill.com\/kb\/","name":"CCBill Knowledge Base","description":"","publisher":{"@id":"https:\/\/ccbill.com\/kb\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ccbill.com\/kb\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ccbill.com\/kb\/#organization","name":"CCBill","url":"https:\/\/ccbill.com\/kb\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ccbill.com\/kb\/#\/schema\/logo\/image\/","url":"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/ccbill-logo.png","contentUrl":"https:\/\/ccbill.com\/kb\/wp-content\/uploads\/2020\/10\/ccbill-logo.png","width":160,"height":70,"caption":"CCBill"},"image":{"@id":"https:\/\/ccbill.com\/kb\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/ccbillBIZ\/","https:\/\/x.com\/CCBillBIZ","https:\/\/www.linkedin.com\/company\/ccbill","https:\/\/www.youtube.com\/c\/CCBillBiz"]},{"@type":"Person","@id":"https:\/\/ccbill.com\/kb\/#\/schema\/person\/054b4aa0928b00dbb64b830a2be8da82","name":"Artur Banas","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ccbill.com\/kb\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/278e436cdf4785ca9f2835fc27f5bd094bdce4f1dba43323b98815b361785009?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/278e436cdf4785ca9f2835fc27f5bd094bdce4f1dba43323b98815b361785009?s=96&d=mm&r=g","caption":"Artur Banas"}}]}},"_links":{"self":[{"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/posts\/474","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/comments?post=474"}],"version-history":[{"count":33,"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/posts\/474\/revisions"}],"predecessor-version":[{"id":5182,"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/posts\/474\/revisions\/5182"}],"wp:attachment":[{"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/media?parent=474"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/categories?post=474"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ccbill.com\/kb\/wp-json\/wp\/v2\/tags?post=474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}