1. Introduction
By default, Angular modules are eagerly loaded. This means that all NgModules are loaded as soon as the application loads. All NgModules are loaded whether they are required or not. This increases the load time of the page. This is not a good design. Suppose there are certain modules in your application which are rarely used, then it will be a good design to load these modules only when they are needed.
Lazy loading of modules helps in keeping the bundle size less and improve page load time.
2. What you’ll do in this tutorial?
You’ll do the following in this tutorial:
- Create a new application with routing enabled.
- Create two modules.
- Enable lazy loading of modules.
- Verify the lazy loading of modules.
You’ll understand the changes required to enable lazy loading of feature modules in application.
3. How to enable lazy loading in application?
3.1 Remove lazy-loaded module from the imports
array of AppModule
.
3.2 To lazy load a module in Angular, use loadChildren
instead of Component
in AppRoutingModule
routes configuration.
const routes: Routes = [ { path: 'admin', loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule), }, { path: 'user', loadChildren: () => import('./user/user.module').then((m) => m.UserModule), }, ];
3.3 The route for the component is to be added in the lazy-loaded module’s routing module.
const routes: Routes = [{ path: '', component: AdminComponent }];
4. Step-by-step implementation of lazy loading
Step 1: Create an application
We’ll create a new application to demonstrate lazy-loading of modules. If you already have an application, you can use that one too. The application should have routing enabled.
ng new lazy-loading-example --routing
This will create a new application lazy-loading-example
. The application will have AppRoutingModule
to have route configuration.
Step 2: Create feature modules
We’ll create two feature modules – admin
and user
, to demonstrate lazy-loading of modules in our application. Run the following commands to generate the modules:
ng generate module admin --route admin --module app.module
ng generate module user --route user --module app.module
admin
anduser
are the name of modules in the command.- Routing is enabled for these modules and each module will have its own routing module –
AdminRoutingModule
andUserRoutingModule
. - Commands generate
AdminComponent
andUserComponent
inadmin
anduser
folders respectively. - Lazy loading configuration is automatically generated in
AppRoutingModule
.
const routes: Routes = [ { path: 'admin', loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule), }, { path: 'user', loadChildren: () => import('./user/user.module').then((m) => m.UserModule), }, ];
- Route configuration of
AdminComponent
is automatically added toAdminRoutingModule
.
const routes: Routes = [{ path: '', component: AdminComponent }];
- Route configuration of
UserComponent
is automatically added toUserRoutingModule
const routes: Routes = [{ path: '', component: UserComponent }];
Step 3: Change UI to test lazy loading
Change app.component.html
file to the following:
<h1> {{ title }} </h1> <button routerLink="/admin">Admin</button> <button routerLink="/user">User</button> <button routerLink="">Home</button> <router-outlet></router-outlet>
This will add three buttons, Customers
, Orders
and Home
. The objective is to load the AdminModule
when Admin
button is clicked, load UserModule
when User
button is clicked and Home
is the default page.
Step 4: Add route configuration for Home button in AdminRoutingModule
{ path: '', redirectTo: '', pathMatch: 'full', },
Following is the complete code of files we discussed.
src/app/admin/admin-routing.module.ts
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { AdminComponent } from './admin.component'; const routes: Routes = [{ path: '', component: AdminComponent }]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule], }) export class AdminRoutingModule {}
src/app/admin/admin.module.ts
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { AdminRoutingModule } from './admin-routing.module'; import { AdminComponent } from './admin.component'; @NgModule({ declarations: [ AdminComponent ], imports: [ CommonModule, AdminRoutingModule ] }) export class AdminModule { }
src/app/admin/user-routing.module.ts
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { UserComponent } from './user.component'; const routes: Routes = [{ path: '', component: UserComponent }]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class UserRoutingModule { }
src/app/admin/user.module.ts
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { UserRoutingModule } from './user-routing.module'; import { UserComponent } from './user.component'; @NgModule({ declarations: [ UserComponent ], imports: [ CommonModule, UserRoutingModule ] }) export class UserModule { }
src/app/app-routing.module.ts
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: 'admin', loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule), }, { path: 'user', loadChildren: () => import('./user/user.module').then((m) => m.UserModule), }, { path: '', redirectTo: '', pathMatch: 'full', }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) export class AppRoutingModule {}
src/app/app.component.html
<h1> {{ title }} </h1> <button routerLink="/admin">Admin</button> <button routerLink="/user">User</button> <button routerLink="">Home</button> <router-outlet></router-outlet>
src/app/app.module.ts
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 { }
Step 5: Verify the lazy loading of modules.
- Run the application using
ng serve
command. The output should like this:
- Open the browser “Network” tab as shown and click on the “Admin” button.
Observe the loading of file src_app_admin_admin_module_ts.js
.
Now clear the list and click on “User” button and observe the src_app_user_user_module_ts.js
is loaded. If the output is same as mentioned then your lazy-loading configuration is working fine.
5. Conclusion
In this tutorial, we discussed lazy loading of NgModules. We also discussed the benefits and step-by-step implementation. We hope this tutorial was informative. Happy learning!