Lazy loading is a design pattern in Angular that delays the loading of feature modules until they are required. Instead of loading all modules at the application startup, Angular only loads the necessary modules and their associated components, services, and assets as needed.
Lazy loading is implemented using Angular's powerful router to load modules dynamically based on user navigation. This improves the application's startup time by reducing the amount of code that needs to be downloaded and processed initially.
How Lazy Loading Works in Angular?
Lazy loading in Angular relies on the router configuration. When the user navigates to a specific route, Angular dynamically loads the corresponding feature module. This process is defined in the RouterModule using the loadChildren property, which specifies the path to the feature module.
For example, if you have a feature module named AdminModule that you only want to load when the user navigates to the /admin route, you configure the router to lazy-load the AdminModule only when the /admin path is accessed.
Traditional Lazy-Loading with Routes
The standard method for lazy-loading in Angular involves configuring your app's routes to load modules on demand. In this approach, the loadChildren syntax is used to lazy-load the FeatureModule when the user navigates to the /feature route. This ensures that the module is loaded only when it's needed. Here's how you can do it:
Syntax:
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) },
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', redirectTo: '/home' }
];
Preloading Strategy
To improve the user experience, you can preload some lazy-loaded modules after the initial application load. Angular provides a built-in strategy for this.With PreloadAllModules, Angular will load the modules in the background, minimizing the delay when the user navigates to a route that requires a lazy-loaded module.
Syntax:
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
exports: [RouterModule]
})
export class AppRoutingModule { }
Dynamic Component Loading
In certain cases, you might need to load components dynamically within a lazy-loaded module. This approach allows you to instantiate components at runtime.This technique is useful for more advanced use cases where you want to control component instantiation at runtime.
Syntax:
// Dynamic component loading example
@Component({
selector: 'app-dynamic',
template: '<ng-container #container></ng-container>'
})
export class DynamicComponent {
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
loadComponent(component: Type<any>) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
this.container.createComponent(componentFactory);
}
}
Steps to Create the Application (Install Required Modules)
To create an Angular application with lazy-loaded modules, follow these steps:
Step 1. Install Angular CLI (if not already installed):
npm install -g @angular/cliStep 2. Create a new Angular application:
ng new lazyloading
cd lazyloading
Step 3. Generate a feature module:
ng generate module gfg --routesStep 4. Create components in the gfgmodule:
ng generate component gfg/contest
Folder Structure

Dependencies
"dependencies": {
"@angular/animations": "^18.0.0",
"@angular/common": "^18.0.0",
"@angular/compiler": "^18.0.0",
"@angular/core": "^18.0.0",
"@angular/forms": "^18.0.0",
"@angular/platform-browser": "^18.0.0",
"@angular/platform-browser-dynamic": "^18.0.0",
"@angular/platform-server": "^18.0.0",
"@angular/router": "^18.0.0",
"@angular/ssr": "^18.0.0",
"express": "^4.18.2",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
}
Example: Below is a complete example of how lazy-loading is implemented in an Angular application:
App Component
Below is the code example having app.component.html, app.component.css. app.routes.ts,app.component.ts and main.ts
<!-- src\app\app.component.html -->
<h1>This is Lazy Loading tutorial by gfg</h1>
<router-outlet></router-outlet>
/*src\app\app\component.css */
h1 {
color: green;
text-align: center;
}
// src\app\app.routes.ts
import { provideRouter } from '@angular/router';
import { AppComponent } from './app.component';
export const routes = [
{ path: '', component: AppComponent },
{
path: 'gfg',
loadChildren: () => import('./gfg/gfg.module').then((m) => m.GfgModule),
},
];
//src/app/app/component.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'lazyLoading';
}
//src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { provideRouter } from '@angular/router';
import { routes } from './app/app.routes';
bootstrapApplication(AppComponent, {
providers: [provideRouter(routes)],
}).catch(err => console.error(err));
gfg.module.ts and gfg-routing.modules.ts
Below is the core example of gfg module and gfg routing module having all the imports declarations and routes added.
// src/app/gfg/gfg.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { ContestComponent } from './contest/contest.component';
const routes: Routes = [
{ path: '', component: ContestComponent }, // When /gfg is accessed
{ path: 'contest', component: ContestComponent } // When /gfg/contest is accessed
];
@NgModule({
declarations: [ContestComponent],
imports: [
CommonModule,
RouterModule.forChild(routes)
]
})
export class GfgModule { }
//src/app/gfg/gfg-routing.modules.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ContestComponent } from './contest/contest.component';
const routes: Routes = [
{ path: 'contest', component: ContestComponent } // Corrected path
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class GfgRoutingModule { }
Contest Component
Below is the code of Contest Component which gets lazily loaded having HTML, CSS and JavaScript code.
<!-- src/app/gfg/contest/contest.component.html -->
<h2>This component is lazy loaded</h2>
/* src/app/gfg/contest/contest.component.css */
h2 {
color: green;
text-align: center;
font-style: italic;
margin-top: 10%;
}
//src/app.gfg/contest/contest.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-contest',
templateUrl: './contest.component.html',
styleUrls: ['./contest.component.css']
})
export class ContestComponent {
// Example of a public property
public contestName: string = 'Angular Coding Contest';
// Example of a public method
public getContestDetails(): string {
return `Welcome to the ${this.contestName}! Prepare to challenge your skills.`;
}
}