Skip to content
intermediate Phase 8 · Routing and Navigation Guards

Lazy Loading Feature Routes

Defer feature code until the user first navigates to it.

40m
0 problems
Topic Progress 0%

Lazy Loading with loadChildren

Lazy loading defers downloading feature code until the user first navigates to it, reducing the initial bundle size.

Lazy Loading a Feature Module

// app.routes.ts
export const routes: Routes = [
  { path: '', component: HomeComponent },
  {
    path: 'admin',
    loadChildren: () =>
      import('./admin/admin.routes').then(m => m.ADMIN_ROUTES),
  },
];
// admin/admin.routes.ts
export const ADMIN_ROUTES: Routes = [
  { path: '', component: AdminDashboardComponent },
  { path: 'users', component: AdminUsersComponent },
  { path: 'settings', component: AdminSettingsComponent },
];

Lazy Loading a Single Component

export const routes: Routes = [
  { path: '', component: HomeComponent },
  {
    path: 'reports',
    loadComponent: () =>
      import('./reports/reports.component').then(m => m.ReportsComponent),
  },
];

How Lazy Loading Works

  1. The main bundle loads with only the essential code
  2. When the user navigates to /admin, the browser downloads the admin chunk
  3. The chunk is cached for subsequent visits

Bundle Size Impact

Without lazy loading:
  main.js — 500 KB (all features included)

With lazy loading:
  main.js — 150 KB (only essential code)
  admin.js — 100 KB (downloaded on first visit to /admin)
  reports.js — 80 KB (downloaded on first visit to /reports)

Preloading Strategies

import { provideRouter, withPreloading } from '@angular/router';
import { PreloadAllModules } from '@angular/router';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withPreloading(PreloadAllModules)),
  ],
};
Strategy Behavior
NoPreloading (default) Only load chunks on navigation
PreloadAllModules Preload all lazy chunks after initial load
Custom strategy Selective preloading based on conditions

Custom Preloading Strategy

Custom preloading strategies let you selectively preload modules based on data attributes.

Custom Preloading Strategy

import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of, timer } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

export class SelectivePreloadingStrategy implements PreloadingStrategy {
  preloadedModules: string[] = [];

  preload(route: Route, load: () => Observable<any>): Observable<any> {
    if (route.data?.['preload']) {
      // Delay preload by 5 seconds
      return timer(5000).pipe(
        mergeMap(() => {
          this.preloadedModules.push(route.path!);
          return load();
        })
      );
    }
    return of(null);
  }
}
export const routes: Routes = [
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES),
    data: { preload: true },
  },
];
export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withPreloading(SelectivePreloadingStrategy)),
  ],
};

Quicklink Strategy (Angular 18+)

Preloads routes when the user hovers over or touches a link:

import { withPreloading } from '@angular/router';
import { QuicklinkStrategy } from 'ngx-quicklink';

provideRouter(routes, withPreloading(QuicklinkStrategy));

Verifying Lazy Loading

# Build and analyze chunks
ng build --configuration production

# Check the dist folder for separate chunks
dist/my-app/browser/
├── main.js
├── admin-XXXX.js
└── reports-XXXX.js

Each lazy-loaded route produces a separate chunk file.

Quiz

1. What does loadChildren do?

Question 1 options

2. What is the benefit of lazy loading?

Question 2 options

3. How do you preload all lazy modules after initial load?

Question 3 options

Flashcards

Question

How do you lazy load a feature module?

Answer

loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES)

Question

What is the benefit of lazy loading?

Answer

Smaller initial bundle size — feature code downloads on first navigation.

Question

How do you preload all lazy modules?

Answer

provideRouter(routes, withPreloading(PreloadAllModules))

Revision Notes

Key Takeaways

  • 1. loadChildren defers feature code until first navigation
  • 2. loadComponent lazy-loads single standalone components
  • 3. PreloadingAllModules warms critical chunks after initial load
  • 4. Custom preloading strategies enable selective preloading

Interview Tips

  • • Explain the bundle size benefits of lazy loading
  • • Be ready to describe preloading strategies
  • • Mention loadComponent for single-component lazy loading

Cheat Sheet

Lazy Loading Cheat Sheet

Lazy load module:

loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES)

Lazy load component:

loadComponent: () => import('./reports/reports.component').then(m => m.ReportsComponent)

Preload all:

provideRouter(routes, withPreloading(PreloadAllModules))

Custom preloading:

provideRouter(routes, withPreloading(MyStrategy))

Continue Learning

Before You Start

Related Reading