Lazy loading in Angular (Put It to Work on Your Website) -- (r)

Jan 16, 2023
Illustration: The page-loading wait — why we need lazy loading in Angular.

To reduce load time and improve the overall experience of your clients, employ a technique referred to as lazy load. It is a native Angular feature allows you to only load the essential components of your web application first, then load other modules as required.

In this article we will discuss lazy loading, and how it could improve the speed of your website application.

What exactly is Lazy Loading?

Lazy loading is commonly utilized for video and image files on sites that host many content. Instead of loading every media in one go, which can consume a significant amount of bandwidth and bog down page views, those elements are loaded as soon as their location on the webpage is set to scroll into view.

Angular is a single-page application framework which relies on JavaScript for a large portion of its capabilities. Your application's library of JavaScript can easily become large when the application grows and this comes with an rise in data usage and loading time. To speed things up, you can use lazy loading to first fetch required modules and defer the loading of the other modules until they are needed.

The benefits from Lazy Loading in Angular

Lazy loading has advantages to improve the user experience of your website. They include:

  • Faster load time: JavaScript contains instructions for displaying your page and loading the data. Due to this, it's a render-blocking resource. It means that the browser has to wait to load all of JavaScript before rendering your page. When lazy loading in Angular, the JavaScript is split into chunks which are loaded in a separate. The initial chunk contains only logic that is needed for the main section of the page. The page is loaded fast before the rest of the modules are loaded slowly. If you reduce the size of your initial chunk, your site load faster and render faster.
  • Use less data: By splitting the data into smaller chunks and then processing it according to the need, you might reduce the amount of bandwidth you use.
  • Conserved browser resources: Since the browser loads only the chunks that are needed so it won't eat up memory and CPU trying to interpret and render code that isn't required.

Implementing Lazy Loading in Angular

To follow along with this guide, you'll require the following items:

  • NodeJS installed
  • Basic knowledge of Angular

Step Up Your Project

  npm install -g @angular/cli  

After that, create an application called Lazy Loading Demo. This is how it works:

  new lazy-loading demo --routing  

The command is used to create a new Angular project with routing. You'll be working exclusively within the src/app folder. This folder includes the source code of the app. This folder contains your main routing file, app-routing.module.ts. The structure of the folder must look as follows:

Screenshot: The Angular folder structure displayed in a terminal.
The folder structure of an Angular project.

Make a Feature Module using Routes

Next, you'll create an feature module which will load slowly. In order to create the module, run this command:

  ng generate module blog --route blog --module app.module  

The command will create a new module called BlogModule, along with routing. If you open src/app/app-routing.module.ts, you will see it now looks like this:

import  NgModule  from '@angular/core';
 import  RouterModule, Routes  from '@angular/router';
 
 const routes: Routes = [  path: 'blog', loadChildren: () => import('./blog/blog.module').then(m => m.BlogModule) ];
 
 @NgModule(
 imports: [RouterModule.forRoot(routes)],
 exports: [RouterModule]
 )
 export class AppRoutingModule   
 

The most important part in lazy loading is the third line:

const routes: Routes = [  path: 'blog', loadChildren: () => import('./blog/blog.module').then(m => m.BlogModule) ];
 

That line is what defines the route. The route for the blog uses an argument called the loadChildren argument instead of the component. Its loadChildren argument instructs Angular to use lazy loading of the route -- to load the module dynamically only when the route is reached, then bring it back on the route. The module specifies itself as a child route, for example, blog/**. blog/**, in its routing.module.ts file. The blog module that you created looks like this:

import  NgModule  from '@angular/core';
 import  RouterModule, Routes  from '@angular/router';
 import  BlogComponent  from './blog.component';
 
 const routes: Routes = [ path: '', component: BlogComponent ];
 
 @NgModule(
 imports: [RouterModule.forChild(routes)],
 exports: [RouterModule]
 )
 export class BlogRoutingModule  
 
 

This routing file contains a single route, ''. It resolves to the blog and redirects towards the BlogComponent. You can add more components and define those routes in the file.

For example, if you wanted to add the component to pull information about a specific blog, you can make the component using this command:

  ng generate component blog/detail  

That generates the component that contains the blog's information and it is added into the module for blogs. If you want to add a route for it then you simply need to add it to your route array:

const routes: Routes = [ path: '', component: BlogComponent ,
 path:"/:title",component: DetailComponent];
 

This adds a route that resolves for blog/:title (for example, blog/angular-tutorial). The list of routes in this bundle is lazy loaded and is not part of the bundle that was initially created.

Verify Lazy Loading

You can check if lazy loading is functioning through running an ng serve and observing the output. On the lower part of your output, you should get the following:

Screenshot: Output of Angular's ng serve command in the terminal.
Verifying lazy loading using an Angular's service ng.

The output above is divided in two sections: Initial Chunk Files are the ones that load when the site first loads. Lazy Chunk Filesare lazy loaded. The blog module is described in the following example.

Verifying for lazy loading through Browser Network Logs

Another way to confirm lazy loading is to use an option called the Network tab within the browser's Developer Tools panel. (On Windows, that's F12 in Chrome and Microsoft Edge, and Ctrlor ShiftI I in Firefox. If you're using a Mac it's Command- OptionI I in Chrome, Firefox and Safari.)

Select the filter JS filter so that you can view only JavaScript files that are loaded onto the internet. Following the initial loading of the app, you should get something like this:

Screenshot: Angular JavaScript files logged in Developer Tools.
The initial log of JavaScript downloads viewed in Developer Tools.

When you navigate to /blog, you will notice a new chunk, src_app_blog_blog_module_ts.js, is loaded. This means your module was requested only when you clicked on that link and is lazily loaded. The network log should appear like this:

Screenshot: Updated view of Angular JavaScript files logged in Developer Tools.
Downloads with lazy-loaded modules are that are logged by Developer Tools.

Lazy Loading Vs Eager Loading

In order to compare, we'll create an eagerly loaded module and observe how it affects the size of the file as well as loading time. To demonstrate this, you'll develop a module to authenticate. The module will require a quick loading, as authentication is something you might need all users to complete.

Create an AuthModule by running this command from the CLI

  ng generate module auth --routing --module app.module  

That generates the module and the routing file. The module is also added in app.module.ts. app.module.ts file. But, unlike the command we employed to create a module last time the one we're using this time doesn't have lazy-loaded routes. It makes use of the "-routing" parameter instead of the --route parameter name>. That adds the authentication module into the imports array in app.module.ts:

 @NgModule(
 declarations: [
 AppComponent
 ],
 imports: [
 BrowserModule,
 AppRoutingModule,
 AuthModule //added auth module
 ],
 providers: [],
 bootstrap: [AppComponent]
 )

Adding AuthModule to the AppModule imports array means the authentication module is included in the first chunk files, and is integrated into the overall JavaScript bundle. For confirmation test, run ng serve once more and check the output:

Screenshot: Angular scripts after authentication module is added.
Output from the Angular's ng serve command after authentication module is installed.

As you can see, the authentication module is not integrated into the lazy chunk files. Furthermore, the size of the first bundle has grown. Its main.js file almost has doubled in size. It's gone from 8KB to KB. For this instance, the increment isn't that significant since the components don't contain much code. But, as you fill the components with logic, the file size will rise and make a compelling case to use lazy loading.

Summary

  • Simple setup and management on My Dashboard. My dashboard
  • 24 hour expert assistance
  • The top Google Cloud Platform hardware and network, that is powered by Kubernetes to ensure maximum capacity
  • Enterprise-level Cloudflare integration for speed and security
  • Global audience reach with as many as 35 data centers as well as 275+ PoPs worldwide