← Back to Chapters

Lazy Loading Modules

? Lazy Loading Modules

Angular   Routing & Modules

? Quick Overview

Lazy loading in Angular lets you load feature modules only when their routes are visited, instead of loading everything at application startup. This reduces the initial bundle size and makes your app feel faster, especially for large projects with many features.

? Key Concepts

  • Feature Module – A separate Angular module that groups related components, pipes and services.
  • Lazy Loading – Defers loading of a feature module until its route is activated.
  • RouterModule.forChild() – Used inside feature modules for their own routing configuration.
  • loadChildren – A route property in the root routing module that points to the lazily loaded module.
  • Route-Based Code Splitting – Angular CLI automatically splits bundles so each lazy module is loaded on demand.

? Syntax & Theory

To use lazy loading, you typically:

  1. Create a feature module (for example, ProductsModule).
  2. Configure its internal routes using RouterModule.forChild().
  3. Configure the main app routes with a loadChildren property that points to this module.
  4. Navigate to the lazy route, causing Angular to dynamically load the module bundle.

The lazy-loaded module is only requested when the user hits a specific route such as /products, which keeps the initial load light and improves perceived performance.

? Code Example 1 – Creating a Feature Module

products.module.ts

? View Code Example
// Feature module with its own routing
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProductsComponent } from './products.component';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: '', component: ProductsComponent }
];

@NgModule({
  declarations: [ProductsComponent],
  imports: [CommonModule, RouterModule.forChild(routes)]
})
export class ProductsModule { }

? Code Example 2 – Configuring Lazy Loading in App Routing

app-routing.module.ts

? View Code Example
// Root routing configuration with lazy loading
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: 'products',
    loadChildren: () =>
      import('./products/products.module').then(m => m.ProductsModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

? Live Behaviour / Explanation

  • The ProductsModule defines a route with an empty path ('') that maps to ProductsComponent. When the module is loaded, visiting /products shows this component.
  • In the root routes, the loadChildren property uses a dynamic import to reference ./products/products.module and resolve ProductsModule.
  • When the user navigates to /products, Angular automatically:
    1. Downloads the separate bundle for ProductsModule.
    2. Initialises the module and registers its child routes.
    3. Displays ProductsComponent in the configured router outlet.
  • Until the user visits /products, the module code is not loaded, which reduces the initial bundle size and speeds up app startup.

✅ Tips & Best Practices

  • Use lazy loading for feature modules that are not needed immediately at startup (e.g., admin areas, reports, settings).
  • Keep feature module dependencies small and focused so their lazy-loaded bundles stay lightweight.
  • Always use RouterModule.forChild() inside lazy-loaded feature modules; use forRoot() only in the main app routing module.
  • Combine lazy loading with route guards (like CanLoad or CanActivate) to protect secure sections.
  • Double-check the import path used in loadChildren to avoid runtime loading errors.

? Try It Yourself / Practice

  • Create a UsersModule in your Angular app and configure it for lazy loading on the route /users.
  • Add multiple components (for example, UserListComponent, UserDetailComponent) and set up child routes using RouterModule.forChild().
  • Navigate to the lazy-loaded route in the browser and open DevTools > Network tab to observe the extra JS bundle being loaded on demand.
  • Protect your UsersModule with a CanLoad guard so that only authenticated users can load it.
  • Refactor an existing large Angular app by moving rarely used sections into lazy-loaded feature modules and measure the change in initial bundle size.