Lazy Loading Scripts and Styles in Angular

| By Maina Wycliffe | | | Angular

In my earlier post, I covered about lazy loading of angular modules. In this post, I will cover lazy loading of scripts and styles, both external and local. The goal of this post is to show how you can defer loading of a script or style and load it manually later when you need.

This also works perfectly with external scripts that if added to the index.html file of your project would have a negative impact on performance. It works well with styles and scripts that are needed for a specific case. One such scenario that spring to mind is handling payment using PayPal.

In most cases, payment is usually processed only after a customer has order an item not before. In this case, loading PayPal by placing the script tags at the index.html would negatively impact performance while it’s only needed at the last step for payment processing.

Loading Scripts and Styles on Demand

You will most like be loading the scripts in a component. To load the style or script, we are going to use document.CreateElement method to add a new script/style element.

For the script, we will create new scripts tags with the source pointing to our script URL. For the style,  we will create new link element in the header, with HREF to our style URL.

To load our script, we begin by creating a new method loadExternalScript(scriptURL),  which will return a promise. A promise will make it easier to ensure that we will use our script after it has been loaded successfully and not before.

return new Promise(resolve => {
  const scriptElement = document.createElement('script');
  scriptElement.src = scriptUrl;
  scriptElement.onload = resolve;
  document.body.appendChild(scriptElement);
});

The same goes for our style, where we will create a new method and then return a promise:

private loadExternalStyles(styleUrl: string) {
  return new Promise((resolve, reject) => {
    const styleElement = document.createElement('link');
    styleElement.href = styleUrl;
    styleElement.onload = resolve;
    document.head.appendChild(styleElement);
  });
}

You can wrap the above two methods in a class or service if you wish. It will make it easier to reuse the methods all over your class easily. Then, call the methods to load the scripts/style as show below:

this.loadExternalScript('url/to/your/scripts').then(() => {}).catch(() => {});
this.loadExternalStyles('url/to/your/styles).then(() => {}).catch(() => {});

And that’s it. You can now load styles/scripts on demand and not before. In the next step, I am going to cover how to lazy load local scripts.

Lazy Loading Local/Internal Scripts and Styles

When Angular CLI is building your application, all the styles and scripts added to the angular.json file are automatically added to the index.html, meaning they will be preloaded before rendering.

"architect": {  
 "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      "styles": [
        "src/styles.css"
      ],
      "scripts": [
        "src/some-script.js"
      ],
      //...

To avoid this, you can specify that a specific script/style is to be lazy loaded and angular will just output a bundle and won’t add it to the index.html. You do this by specifying the script/style in object format, instead of a simple string as shown above. The object formats allows you to provide more information to the CLI about how to handle a specific style sheet or script. This information includes the output name, whether to lazy load and the source of the style/script.

{
  "input":"path/to/your/lazy-script.js",
  "lazy": true,
  "bundleName": "lazy-loaded-script"
},

You also must specify the output name (bundleName) to be able to reference to it later. If you don’t, Angular CLI will randomly generate a bundle name, which will change on each build.

"scripts": [
  "src/some-script.js",
  {
    "input": "path/to/your/lazy-script.js",
    "lazy": true,
    "bundleName": "lazy-loaded-script"
  },
],
"styles":
  [
    "src/some-styles.css",
    {
      "input": "path/to/your/lazy-style.css",
      "lazy": true,
      "bundleName": "lazy-loaded-style"
    },
],
Optimizing your Angular App using Lazy Loading

Lazy loading is a technique where you defer loading of content until such a time it’s needed. In single page apps (SPA), usually the whole …

Read More
Angular 6 - Angular CLI Workspaces

One of the least talked about features of Angular 6 is Angular CLI Workspaces. Workspaces or Angular CLI Workspaces give angular developers …

Read More
Working with Environment Variables in Angular 6

It’s common for developers to have multiple application versions that target different environments i.e. development and production. It’s …

Read More
Top VSCode Extensions for Angular Developers

Since the release of VSCode a few years ago, it has become very popular among developers. VSCode is my favorite text editor and use it every …

Read More
UI Libraries and Frameworks for Angular 6

UI Libraries and Frameworks make it easier for developers to build clean and consistent User Interfaces (UI). They provide components, …

Read More
Angular – Managing Authentication State Using NGXS

Managing an apps Authentication State is a vital task that as Single Page App (SPA) developers, have to handle very often. It’s every …

Read More

Comments