Angular Standalone Lazy Loading

By Arvind Rai, 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)
            }
        ]
    },
    ......
]; 
The 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)
    },
    ......
]; 
The 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

The import() 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')
    }
]; 
Find the default exports.
employee-detail.component.ts
@Component({
    standalone: true,
    ......
})
export default class EmployeeDetailComponent implements OnInit {
    ......
} 
dev-routes.constant.ts
export default [
    { path: 'team', component: TeamComponent },
    { path: 'tech', component: TechComponent } 
] as Route[]; 

4. Complete Example

src/main.ts
import { 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)
    ]
});  
src/app.component.html
<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> 
src/constants/routes.constant.ts
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)
    }
]; 
myApp/src/constants/dev-routes.constant.ts
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 } 
]; 
src/components/dev.component.ts
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 {
} 
src/components/employee-detail.component.ts
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);
    }
} 
src/components/employee.component.ts
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;
        });
    }
} 
src/components/team.component.ts
import { Component } from "@angular/core";

@Component({
    standalone: true,
    template: `
       <h3>Team</h3> 
       <p>Java Team</p>
       <p>Front-End Team</p>
    `
})
export class TeamComponent {
} 
src/components/tech.component.ts
import { Component } from "@angular/core";

@Component({
    standalone: true,
    template: ` 
        <h3>Technology</h3>
        <p>Java</p>
        <p>Spring</p>
        <p>Angular</p>
    `
})
export class TechComponent {
} 
src/services/person.ts
export interface Person {
    id: number;
    name: String;
    age: number;
    city: string;
} 
src/services/person.service.ts
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))
    );
  }
} 
Find the print screen of the output.
Angular Standalone Lazy Loading

5. Reference

6. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us