Angular Standalone Lazy Loading
May 28, 2023
In lazy loading, components are loaded on demand and hence the application start will be faster. Lazy loading is performed by loadComponent
and loadChildren
properties of Route
interface.
loadComponent : Specifies a lazy-loaded component.
loadChildren : Specifies a lazy-loaded child routes.
On this page we will create Angular application with lazy loading of standalone components.
1. Using loadComponent
for Single Component
The loadComponent
loads a single component lazily on demand. Find the code to use loadComponent
in route configuration.
routes.constant.ts
export const ROUTES: Route[] = [ { path: 'emp', component: EmployeeComponent, children: [ { path: 'emp-detail/:id', loadComponent: () => import('src/components/employee-detail.component') .then(mod => mod.EmployeeDetailComponent) } ] }, ...... ];
EmployeeDetailComponent
will be loaded lazily when the path /emp/emp-detail/:id is accessed.
2. Using loadChildren
for many routes at once
The loadChildren
loads lazily many routes at once. Find the code to use loadChildren
in route configuration.
routes.constant.ts
export const ROUTES: Route[] = [ { path: 'dev', component: DevComponent, loadChildren: () => import('src/constants/dev-routes.constant') .then(mod => mod.DEV_ROUTES) }, ...... ];
loadChildren
will load lazily all the components configured in DEV_ROUTES
when the path /dev
is accessed.
dev-routes.constant.ts
export const DEV_ROUTES: Route[] = [ { path: 'team', component: TeamComponent }, { path: 'tech', component: TechComponent } ];
3. Default Exports
Theimport()
used with loadComponent
and loadChildren
can directly load default
exports. In this case, we skip .then()
for such lazy loading operations.
Find the example.
routes.constant.ts
export const ROUTES: Route[] = [ { path: 'emp', component: EmployeeComponent, children: [ { path: 'emp-detail/:id', loadComponent: () => import('src/components/employee-detail.component') } ] }, { path: 'dev', component: DevComponent, loadChildren: () => import('src/constants/dev-routes.constant') } ];
employee-detail.component.ts
@Component({ standalone: true, ...... }) export default class EmployeeDetailComponent implements OnInit { ...... }
export default [ { path: 'team', component: TeamComponent }, { path: 'tech', component: TechComponent } ] as Route[];
4. Complete Example
src/main.tsimport { bootstrapApplication } from '@angular/platform-browser'; import { Component } from "@angular/core"; import { PersonService } from "./services/person.service"; import { RouterModule, provideRouter } from '@angular/router'; import { ROUTES } from './constants/routes.constant'; @Component({ selector: 'app-root', standalone: true, imports: [ RouterModule ], templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { } bootstrapApplication(AppComponent, { providers: [ PersonService, provideRouter(ROUTES) ] });
<nav class="parent-menu"> <ul> <li><a routerLink="/emp" routerLinkActive="active">Employee</a></li> <li><a routerLink="/dev" routerLinkActive="active">Development</a></li> </ul> </nav> <router-outlet></router-outlet>
import { Route } from "@angular/router"; import { DevComponent } from "src/components/dev.component"; import { EmployeeComponent } from "src/components/employee.component"; export const ROUTES: Route[] = [ { path: 'emp', component: EmployeeComponent, children: [ { path: 'emp-detail/:id', loadComponent: () => import('src/components/employee-detail.component') .then(mod => mod.EmployeeDetailComponent) } ] }, { path: 'dev', component: DevComponent, loadChildren: () => import('src/constants/dev-routes.constant') .then(mod => mod.DEV_ROUTES) } ];
import { Route } from "@angular/router"; import { TeamComponent } from "src/components/team.component"; import { TechComponent } from "src/components/tech.component"; export const DEV_ROUTES: Route[] = [ { path: 'team', component: TeamComponent }, { path: 'tech', component: TechComponent } ];
import { Component } from "@angular/core"; import { RouterModule } from "@angular/router"; @Component({ standalone: true, imports: [ RouterModule ], template: ` <ul> <li><a routerLink="team" routerLinkActive="active">Dev Team</a></li> <li><a routerLink="tech" routerLinkActive="active">Dev Technologies</a></li> </ul> <router-outlet></router-outlet> ` }) export class DevComponent { }
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; import { CommonModule } from '@angular/common'; import { switchMap } from 'rxjs/operators'; import { Person } from '../services/person'; import { PersonService } from '../services/person.service'; @Component({ standalone: true, imports: [CommonModule], template: ` <div *ngIf="person"> <h3>Details</h3> {{person.id}} - {{person.name}} - {{person.age}} - {{person.city}} </div> `, styles: ['div { font-weight: bold}'] }) export class EmployeeDetailComponent implements OnInit { person?: Person; constructor(private route: ActivatedRoute, private personService: PersonService) { } ngOnInit() { this.route.params.pipe( switchMap((params: Params) => this.personService.getPersonById(+params['id'])) ).subscribe(person => this.person = person); } }
import { CommonModule } from "@angular/common"; import { Component, OnInit } from "@angular/core"; import { RouterModule } from "@angular/router"; import { Person } from "src/services/person"; import { PersonService } from "src/services/person.service"; @Component({ standalone: true, imports: [ RouterModule, CommonModule ], template: ` <h3>{{heading}}</h3> <div *ngFor="let p of persons"> <p>{{p.name}} | <a [routerLink]="['emp-detail', p.id]">View Detail</a> </p> </div> <router-outlet></router-outlet> ` }) export class EmployeeComponent implements OnInit { heading = "Employee List"; persons?: Person[]; constructor(private service: PersonService) { } ngOnInit() { this.service.getAllPersons().subscribe(data => { this.persons = data; }); } }
import { Component } from "@angular/core"; @Component({ standalone: true, template: ` <h3>Team</h3> <p>Java Team</p> <p>Front-End Team</p> ` }) export class TeamComponent { }
import { Component } from "@angular/core"; @Component({ standalone: true, template: ` <h3>Technology</h3> <p>Java</p> <p>Spring</p> <p>Angular</p> ` }) export class TechComponent { }
export interface Person { id: number; name: String; age: number; city: string; }
import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { Person } from "./person"; @Injectable() export class PersonService { getAllPersons(): Observable<Person[]> { return of( [ { id: 101, name: 'Nilesh', age: 25, city: 'Pune' }, { id: 102, name: 'Pankaj', age: 30, city: 'Delhi' }, { id: 103, name: 'Paramdeep', age: 20, city: 'Noida' } ] ); } getPersonById(pid: number) { return this.getAllPersons().pipe( map(allPersons => allPersons.find(p => p.id === pid)) ); } }
