Angular 9: Lazy Load Components to Enhance App Performance

Image for post
Image for post

The performance of an app is one of the most important parameters to be considered. Neglecting this aspect often leads to a poor user experience.

Before Angular 9, we had heard a lot about the lazy loading of modules for enhancing the performance of an app. But with Angular 9, we have a tremendous feature to lazy load the components as well. This is all thanks to the Ivy engine which made it possible and quite simple. If you are not sure what that is, check out our post where we illustrate what makes it so developer-friendly:

At the end of this blog, we will have a good understanding of how we can leverage component lazy loading in our app to boost its performance.

What is Lazy Loading of Components in Angular and What Does it Do?

It simply means that the component would be downloaded and appended to the DOM only at the time it is required to be rendered.

When we lazy load any component, it is not included in the initial bundle, thus reducing its size. The smaller the bundle size, the faster the app gets rendered.

How to Lazy Load Components in Angular?

Components can be lazy loaded in 2 scenarios:

>> Scenario 1: By appending the component at the end of the DOM

>> Scenario 2: By appending the component somewhere in between the elements of the DOM

Let’s understand the implementation of each by taking an example of nested lazy loading of components in which, on a button action, a base component will load a lazy component which will later load another lazy component.

Prerequisites

  1. npm
  2. Angular 9+
  3. Typescript version 3.6+

Before moving forward, make sure you switch enableIvy to ‘true’. To cross-check it, open tsconfig.json and find/add the below lines:

“angularCompilerOptions”: {“enableIvy”: true}

Good to go? Let's begin implementing!

Implementing Lazy Loading of Components in Angular

Step#1: Use the below command to create a new Angular app.

ng new lazy-load-demo

Step#2: Create two new components that need to be lazy loaded.

ng g c lazy-Comp1 — skip-import — skip-selectorng g c lazy-Comp2 — skip-import — skip-selector
  • skip-import: it is used as we don’t want to import these components in the module
  • skip-selector: this is to skip the selector as it is not required

Step#3: Now add the following code in

app.component.html:

<h1 style=”text-align: center”>LAZY LOADING OF COMPONENTS</h1><div style=”text-align: center;margin-top: 20px;”><button (click)=”firstLazyComp()” style=”margin-right: 5px;background-color: steelblue;font-size: 23px;”><b>Click to load a Lazy comp!! </b></button></div>

app.component.ts:

import { Component, ViewContainerRef, ComponentFactoryResolver } from ‘@angular/core’;@Component({selector: ‘app-root’,templateUrl: ‘./app.component.html’,styleUrls: [‘./app.component.scss’]})export class AppComponent {title = ‘lazy-load-demo’;constructor(private viewContainerRef: ViewContainerRef,private cfr: ComponentFactoryResolver) { }async firstLazyComp() {this.viewContainerRef.clear();const { LazyComp1Component } = await import(‘./lazy-comp1/lazy-comp1.component’);this.viewContainerRef.createComponent(this.cfr.resolveComponentFactory(LazyComp1Component));}}

In app.component.html, we have a button which when clicked calls a function, firstLazyComp(), that will lazy load the LazyComp1Component by appending it at the end of the DOM (based on scenario 1).

The constructor needs to be injected with the following:

  • ViewContainerRef — a container that helps in providing a place in the DOM to add a dynamically created component.
  • ComponentFactoryResolver — used to display the dynamically created component instance.

In the firstLazyComp() method, we first clear viewContainerRef so that it does not contain any other reference. Next, we import the component dynamically and render it using createComponent() and resolveComponentFactory().

This way, LazyComp1Component will be loaded lazily. To verify we can check the network tab:

Image for post
Image for post

After clicking the ‘Click to load a lazy comp!!’ button, the lazy-comp1-component.js file gets loaded as well as rendered.

Image for post
Image for post

Step#4: We also have a button in this lazy-loaded component (i.e. LazyComp1) that will lazy load another component, LazyComp2. But this time the component will not be added at the end of the DOM, but in between the existing elements of the DOM (based on scenario 2).

Add the following code in:

lazy-comp1.component.html:

<div style=”text-align: center; background-color: aliceblue;height: 300px”><h4>SCENARIO 1 :<h2>Look I’m appended at the end of the DOM…</h2></h4><div style=”background-color:lightblue;margin: 1% 28%;”><ng-template #loadLazyComponent></ng-template></div><button (click)=”secondLazyComp()” style=”margin-left: 5px;background-color: steelblue;font-size: 23px;”><b>Try Me!! I’m also Lazy</b></button></div>

lazy-comp1.component.ts:

import { Component, OnInit, ViewContainerRef, ViewChild, ComponentFactoryResolver } from ‘@angular/core’;@Component({templateUrl: ‘./lazy-comp1.component.html’,styleUrls: [‘./lazy-comp1.component.scss’]})export class LazyComp1Component implements OnInit {component;@ViewChild(‘loadLazyComponent’, { read: ViewContainerRef, static: true }) private loadLazyComponent: ViewContainerRef;constructor(private readonly componentFactoryResolver: ComponentFactoryResolver, ) { }ngOnInit() {}secondLazyComp() {if (!this.component) {import(‘../lazy-comp2/lazy-comp2.component’).then(({ LazyComp2Component }) => {this.component = this.componentFactoryResolver.resolveComponentFactory(LazyComp2Component);this.loadLazyComponent.createComponent(this.component);})}}}

As we want to render a component between the existing elements of the DOM, we use ng-template. When we click on the button, it will call a function secondLazyComp(). This time we would be using the template reference variable to render the lazy-loaded component, lazy-comp2.

Find the below component that would be injected in the ng-template of lazy-comp1.component.html.

lazy-comp2.component.html:

<div style=”height: 162px;”>     <h4 style=”text-align: center;padding: 13%”>         SCENARIO 2 : Appended dynamically in between the existing DOM     </h4></div>

So, let’s have a look at the network tab again. We can see that the lazy-comp2-component.js file has been loaded only when it is required to be rendered.

Image for post
Image for post

That’s it! Nested lazy loading of the components has been implemented successfully in our project.

Angular is a trademark of Google LLC. npm is a registered trademark of npm, Inc. DLT Labs is a trademark of DLT Global, Inc.

Author — Charul Bishnoi, DLT Labs™

About the AuthorCharul is an Assistant Manager-Software Engineer at DLT Labs and is currently associated with the DL Tools team. She is skilled in Angular, Android, Node.js, and Java. In her free time, dance is one of her favorite things to do. Also an art lover, she enjoys doing creative activities like painting and decoration.

Written by

DLT Labs is a global leader in Distributed Ledger Technology and Enterprise Products. To know more, head over to: https://www.dltlabs.com/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store