Lazy loading in the Design pattern
Lazy loading is a design pattern commonly used in programming to defer the initialization of an object until the point at which it is needed. This can improve the performance of applications, especially large-scale applications, by loading only the necessary components initially and deferring the loading of other components until they are actually required. In the context of Angular, lazy loading allows you to load NgModules as needed, which can significantly enhance the performance of your application.
In this article, we'll explore how to implement lazy loading in an Angular application and provide a real-time use case involving multiple modules.
Benefits of Lazy Loading
- Improved Load Time: By loading only necessary modules at the start, the initial load time of the application is reduced.
- Optimized Performance: Resources are utilized more efficiently, as unused modules are not loaded until required.
- Scalability: Makes it easier to manage larger applications by breaking them into smaller, more manageable chunks.
Setting up lazy loading in Angular
To demonstrate lazy loading, we’ll create a simple Angular application with multiple modules and load them lazily.
Step 1. Create a new angular project
First, create a new Angular project using the Angular CLI.
ng new lazy-loading-demo
cd lazy-loading-demo
Step 2. Generate Modules and Components
Next, generate a few modules and components. We’ll create two feature modules, AdminModule and UserModule, each with its own component.
ng generate module admin --route admin --module app.module
ng generate component admin/admin-dashboard
ng generate module user --route user --module app.module
ng generate component user/user-dashboard
Step 3. Configure Routing for Lazy Loading
In Angular, lazy loading is implemented using the loadChildren property in the route configuration. The routes for AdminModule and UserModule will be added to the AppRoutingModule.
// 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 { }
Step 4. Define Routes in Feature Modules
Now, define the routes for the components inside each feature module.
// src/app/admin/admin-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
const routes: Routes = [
{ path: '', component: AdminDashboardComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AdminRoutingModule { }
// User Routing Module
// src/app/user/user-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { UserDashboardComponent } from './user-dashboard/user-dashboard.component';
const routes: Routes = [
{ path: '', component: UserDashboardComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class UserRoutingModule { }
Step 5. Import Routing modules in feature modules
Finally, import the respective routing modules in each feature module.
// src/app/admin/admin.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
import { AdminRoutingModule } from './admin-routing.module';
@NgModule({
declarations: [AdminDashboardComponent],
imports: [
CommonModule,
AdminRoutingModule
]
})
export class AdminModule { }
// src/app/user/user.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserDashboardComponent } from './user-dashboard/user-dashboard.component';
import { UserRoutingModule } from './user-routing.module';
@NgModule({
declarations: [UserDashboardComponent],
imports: [
CommonModule,
UserRoutingModule
]
})
export class UserModule { }
Real-Time Use Case
Role-Based Modules
Consider an application where users have different roles, such as Admins and Regular Users. Each role has access to different parts of the application. Using lazy loading, we can load the respective modules only when the user navigates to that part of the application.
For instance, an Admin logs in and navigates to the admin dashboard. The AdminModule will be loaded at this point. Similarly, when a Regular User logs in and navigates to their dashboard, the UserModule will be loaded.
Conclusion
Lazy loading in Angular is a powerful technique to improve the performance and scalability of your applications. By deferring the loading of modules until they are needed, you can significantly reduce the initial load time and optimize resource usage. In this article, we've walked through the steps to implement lazy loading and provided a real-time use case demonstrating its utility. Adopting lazy loading can lead to a smoother, more efficient user experience in your Angular applications.