What is Lazy Loading?

Lazy loading is the process of loading components, modules, or other assets of a website as they're required.

Since Angular creates a SPA (Single Page Application), all of its components are loaded at once. This means that a lot of unnecessary libraries or modules might be loaded as well.

For a small application this would be okay. But as the application grows the load time will increase if everything is loaded at once. Lazy loading allows Angular to load components and modules as and when they're needed.

First of all, to understand how lazy loading works in Angular, we need to understand the basic building blocks of the framework: NgModules.

What are NgModules?

Angular libraries like RouterModule, BrowserModule, and FormsModule are NgModules. Angular Material, which is a third party tool, is also a type of NgModule.

NgModules consist of files and code related to a specific domain or that have a similar set of functionalities.

A typical NgModule file declares components, directives, pipes, and services. It can also import other modules that are needed in the current module.

One of the important advantages of NgModules is that they can be lazy loaded. Let’s have a look at how we can configure lazy loading.

You can check below to see what a basic NgModule file looks like.

How to Create NgModules

In this tutorial, we will create two modules, Module A and Module B, which will be lazy loaded. On the main screen we will have two buttons for loading each module lazily.

Create the Project

Create a new Angular project called lazy-load-demo by executing the below command:

ng new lazy-load-demo --routing --style css
code lazy-load-demo

Here, we are creating a new project with routing. Secondly, we mention the stylesheet format to CSS. The second command opens your project in VS Code.

Root Module

By default, a root module or app module is created under /src/app. Below is the NgModule file that's created.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

First, we import all the required modules and components.

After that, the @NgModule decorator states that the AppModule class is a type of NgModule. The decorator accepts declarations, imports, providers, and bootstrap. Here are the descriptions for each of them:

  • declarations: The components in this module.
  • imports: The modules that are required by the current module.
  • providers: The service providers, if any.
  • bootstrap: The root component that Angular creates and inserts into the index.html host web page.

Main screen

The main screen will have two buttons, Load Module A & Load Module B. As the name suggests, clicking these buttons will lazily load each module.

For that, replace your app.component.html file with the contents below.

<button style="padding: 20px; color: white; background-color: green;" routerLink="a">Load Module A</button>
<button style="padding: 20px; color: white; background-color: blue;" routerLink="b">Load Module B</button>
<router-outlet></router-outlet>

Let’s define the modules for routes a & b.

Lazy Loaded Modules

In order to create lazy loaded modules, execute the below commands:

ng generate module modulea --route a --module app.module
ng generate module moduleb --route b --module app.module

The commands will generate two folders called modulea and moduleb. Each folder will contain its own module.ts, routing.ts and component files.

If you check your app-routing.module.ts you will see the below code for routes:

const routes: Routes = [
  { path: 'a', loadChildren: () => import('./modulea/modulea.module').then(m => m.ModuleaModule) },
  { path: 'b', loadChildren: () => import('./moduleb/moduleb.module').then(m => m.ModulebModule) }
];

It implies that when route a or b is visited, load their respective modules lazily.

On running the project with ng serve, you will see the below screen:

Screenshot-2021-04-25-at-11.18.55-PM
Home Page

When you click the Load Module A button, you will be routed to page a. This is how your screen should look:

Screenshot-2021-04-25-at-11.18.14-PM
Lazily loaded Module A

You should see a similar screen that says moduleb works! when you click on Load Module B.

How to Verify that the Lazy Loading Worked

In order to verify that the files loaded, open the developer tools by pressing F12. After that, visit the Network tab as you can see in the screenshot below. When you refresh the page it will show a few files that were requested.

Network-Tab-1
Network Tab

Go ahead and clear your list of requests by hitting the clear button as shown in the image below.

Screenshot-2021-04-25-at-11.42.21-PM

When you click on the Load Module A, you will see a request for modulea-modulea-module.js as in the screenshot below. This verifies that Module A was lazily loaded.

Screenshot-2021-04-25-at-11.46.50-PM
Module A Loaded

Similarly, when you click Load Module B, the moduleb-moduleb-module.js file is loaded. This verifies that Module B was loaded lazily.

Screenshot-2021-04-25-at-11.47.10-PM
Module B Loaded

Now, when you try to click the buttons it will not load these js files again.

Use Cases for NgModules

As we have seen, it's very easy to create lazy loading modules. There are lots of use cases where they are useful, such as

  • Creating a separate module for pre-login vs post-login screens.
  • For an e-commerce website, vendor facing vs customer facing screens can belong to separate modules. You can also create a separate module for payment.
  • A separate CommonModule which contains shared components, directives, or pipelines is usually created. Directives like Copy Code button, components like up vote/down vote are usually included in a common module.

Conclusion

For smaller websites, it might not matter much that all the modules are loaded at once. But, as the site grows, it’s helpful to have separate modules which are loaded as needed.

Because of lazy loading, load time for the websites can be reduced drastically. This is specially helpful when you are trying to rank higher for SEO. Even if not, shorter loading times means better user experience.

Are you interested in more tutorials? Check these resources out: