Module Lazy Loading in Angular

Posted By : S. Ajit | 20-Oct-2017

Lazy loading is one of the cool feature available in angular. With lazy loading the required module ( Component, Template,Styles,Services etc.. )  gets loaded into browser only when we click on the specific route.

To better understand this lets create a angular app.

STEP 1: Create a basic angular project with angular-cli.

 Install angular-cli with npm.

 

npm install -g @angular/cli

If you don't have npm you have to install NodeJs inorder to get npm 

Now create a folder angular-lazy-loading with angular-cli and run angular project via below commands one by one

 

ng new angular-lazy-loading

cd angular-lazy-loading

ng serve

 STEP 2: Create sample module for lazy loading

Lets create 3 sample module - admin-module, buyer-module and seller-module .  Create folder for these 3 module inside app folder and create html,component,module and route within these folders as shown in screen shot below. 

Lets explore the content of each file and folder:

admin-module:

admin.component.html

 

<div class="container text-center">
  <h1>This is admin module</h1>
  <p>This is a message from component : <span class="text-success">{{msg}}</span></p>
</div>

This is a template for our admin component. I have used bootstrap class in this template. To add bootstrap just include css url to your index.html file like this:

 

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

admin.component.ts

 

import { Component } from '@angular/core';


@Component({
  selector:'admin-module',
  templateUrl:'./admin.component.html'
})

export class AdminComponent{
    msg="Hi, Admin";
}

This is a our admin component 

admin.module.ts 

 

import { NgModule } from '@angular/core';
import { AdminComponent } from './admin.component';
import { AdminRouteModule } from './admin.route.module';

@NgModule({
  imports:[AdminRouteModule],
  declarations:[AdminComponent],
  providers:[],

})

export class AdminModule{

}

This is the admin module which will get lazy loaded via route change. Please note we have included AdminRouteModule in imports which is a module written below, if we don't include AdminRouteModule then lazy loading will not work. 

admin.route.module.ts 

 

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AdminComponent } from './admin.component';

const routes: Routes=[
  {
    path:'',
    component:AdminComponent
  }
]

@NgModule({
  imports:[
    RouterModule.forChild(routes)
  ],
  exports:[
    RouterModule
  ]
})

export class AdminRouteModule{

}

This is the Routing module of our admin module. Here we have used RouterModule.forChild(routes) ,It is used for submodules and lazy loaded modules.

Description for buyer and seller module are same as admin module.

buyer-module: 

buyer.component.html

 

<div class="container text-center">
  <h1>This is buyer module</h1>
  <p>This is a message from component : <span class="text-success">{{msg}}</span></p>
</div>

buyer.component.ts

 

@Component({
  selector:'buyer-module',
  templateUrl:'./buyer.component.html'
})

export class BuyerComponent{
    msg="Hi, Buyer";
}

buyer.module.ts 

 

import { NgModule } from '@angular/core';
import { BuyerComponent } from './buyer.component';
import { BuyerRouteModule } from './buyer.route.module';

@NgModule({
  imports:[BuyerRouteModule],
  declarations:[BuyerComponent],
  providers:[],

})

export class BuyerModule{

}

buyer.route.module.ts 

 

import { NgModule } from '@angular/core';
import { Routes,RouterModule } from '@angular/router';

import { BuyerComponent } from './buyer.component';

const routes: Routes=[
  {
    path:'',
    component:BuyerComponent
  }
]

@NgModule({
  imports:[
    RouterModule.forChild(routes)
  ],
  exports:[
    RouterModule
  ]
})
export class BuyerRouteModule{

}

seller-module: 

seller.component.html

 

<div class="container text-center">
  <h1>This is seller module</h1>
  <p>This is a message from component : <span class="text-success">{{msg}}</span></p>
</div>

seller.component.ts

 

import { Component } from '@angular/core';


@Component({
  selector:'seller-module',
  templateUrl:'./seller.component.html'
})

export class SellerComponent{
    msg="Hi, Seller";
}

seller.module.ts 

 

import { NgModule } from '@angular/core';
import { SellerComponent } from './seller.component';
import { SellerRouteModule } from './seller.route.module';

@NgModule({
  imports:[SellerRouteModule],
  declarations:[SellerComponent],
  providers:[],

})

export class SellerModule{

}

seller.route.module.ts 

 

import { NgModule } from '@angular/core';
import { Routes,RouterModule } from '@angular/router';

import { SellerComponent } from './seller.component';

const routes: Routes=[
  {
    path:'',
    component:SellerComponent
  }
]

@NgModule({
  imports:[
    RouterModule.forChild(routes)
  ],
  exports:[
    RouterModule
  ]
})
export class SellerRouteModule{

}

Other files:

app.component.html

 

<nav class="navbar navbar-default">
<div class="container-fluid">
  <div class="navbar-header">
    <a class="navbar-brand" href="#">Angular Lazy Loading</a>
  </div>
  <ul class="nav navbar-nav">
    <li [ngClass]="{'active': currentRoute=='/buyer'}"><a routerLink="/buyer">Buyer</a></li>
    <li [ngClass]="{'active': currentRoute=='/seller'}"><a routerLink="/seller">Seller</a></li>
    <li [ngClass]="{'active': currentRoute=='/admin'}"><a routerLink="/admin">Admin</a></li>
  </ul>
</div>
</nav>

<router-outlet></router-outlet>

I have added bootstrap navigation bar in main component html and to switch active css based on current route i have used ngClass.  The value for currentRoute is available via component.

app.component.ts

 

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  currentRoute = "/buyer";

  constructor(private router: Router) {

  }

  ngOnInit() {
    this.router.events.subscribe((event) => {
      if (event instanceof NavigationEnd) {
        this.currentRoute = event.url;
      }
    });
  }
}

This is the main component of our application . By default we have set currentRoute value to /buyer and the value for currentRoute is change via route event subscriber. 

app.module.ts

 

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { routes } from './app.route';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(routes)
  ],
  providers: [],
  bootstrap: [AppComponent],
  exports: [ RouterModule ]
})
export class AppModule { }

Main module of application. Here you can see  RouterModule.forRoot(routes) , since this is the main module instead of using forChild we will used forRoot, The value for route is available via below file

app.route.ts

 

import { Routes } from '@angular/router';

export const routes: Routes=[
  {
    path:'',
    redirectTo:'buyer',
    pathMatch: 'full',
  },{
    path:'admin',
    loadChildren:'./admin-module/admin.module#AdminModule'
  },{
    path:'buyer',
    loadChildren:'./buyer-module/buyer.module#BuyerModule'
  },{
    path:'seller',
    loadChildren:'./seller-module/seller.module#SellerModule'
  }
]

Main route of application . We have used loadChildren to load child modules. Consider admin path : admin-module/admin.module#AdminModule . admin-module denote admin module folder name , admin.module denote module file name , #AdminModule denote exported module name.

 

STEP 3: Running the project

This GIF image is enough to show the working of this lazy loading application 

Thanks

About Author

Author Image
S. Ajit

Ajit is a software developer who loves solving problems and programming in C, C++, Java. He also has a passion to learn new technologies.

Request for Proposal

Name is required

Comment is required

Sending message..