ReviseAlgo Logo

Routing

Lazy Loading

Master Angular Lazy Loading, covering route-level code splitting, loadComponent, loadChildren, preloading strategies, and bundle optimization.

Last Updated: July 15, 2026 11 min read

1. Learning Objectives

In this lesson, you will master lazy loading in Angular. By the end of this topic, you will be able to:

  • Explain how lazy loading improves initial page load performance.
  • Use loadComponent to lazy-load standalone components at the route level.
  • Use loadChildren to lazy-load entire route configuration modules.
  • Configure preloading strategies to preload lazy-loaded routes in the background.
  • Verify code splitting by inspecting bundled output chunks.

2. Overview

By default, Angular bundles all components into a single JavaScript file. As the application grows, this file becomes large, slowing down the initial page load. Lazy loading solves this by splitting the application into separate chunks that are downloaded on-demand when the user navigates to the corresponding route.

3. Why This Topic Matters

Lazy loading is critical for production Angular applications:

  • Initial Load Performance: A large enterprise application with dozens of feature modules can produce a multi-megabyte JavaScript bundle. Lazy loading ensures users only download the code they need for the current page, dramatically reducing the Time to Interactive (TTI) metric.
  • Accidental Eager Import: A common mistake is importing a lazy-loaded component directly in a parent module or route file using a standard import statement. This causes the bundler to include the component in the main bundle, defeating the purpose of lazy loading entirely.

4. Real-World Analogy

Think of lazy loading like **a streaming video platform**:

  • Eager Loading (Downloading entire movie library): Without lazy loading, every movie is downloaded to your device upfront before you can watch anything. This takes a very long time and wastes bandwidth.
  • Lazy Loading (Streaming on-demand): Only the movie you select is streamed. Other movies are downloaded only when you choose to watch them.
  • Preloading (Smart buffering): After the current movie starts playing, the platform quietly pre-buffers the next episode in the background, so it loads instantly when you click "Next Episode".

5. Core Concepts

Angular provides two primary lazy loading mechanisms:

  • loadComponent: Lazy-loads a single standalone component using a dynamic import() expression. Best for individual routes mapping to standalone components.
  • loadChildren: Lazy-loads a child routes configuration (either from a standalone routes file or a legacy NgModule). Best for feature areas with multiple nested routes.
  • Preloading Strategies: After the main bundle loads, Angular can preload lazy-loaded chunks in the background. The built-in PreloadAllModules strategy downloads all lazy chunks after the initial render completes.
Mechanism Use Case Syntax
loadComponent Lazy-load a single standalone component. loadComponent: () => import('./path').then(m => m.Comp)
loadChildren Lazy-load an entire child routes configuration. loadChildren: () => import('./path').then(m => m.routes)

6. Syntax & API Reference

Below are route configurations demonstrating both loadComponent and loadChildren:

Enabling Preloading

7. Visual Diagram

This diagram displays the lazy loading lifecycle:

8. Live Example — Full Working Code

Below is a standalone component that is designed to be lazy-loaded:

To verify lazy loading is working correctly, run the production build command and inspect the output:

9. Interactive Playground

Try It Yourself Challenges:

  1. Convert an eagerly loaded route to use loadComponent and verify the build output produces a separate chunk file.
  2. Add a standard import statement for a lazy-loaded component in the parent route file and observe how it defeats code splitting.

10. Common Mistakes

Mistake Why it happens Wrong Correct
Eagerly importing a lazy-loaded component Adding a standard top-level import { SettingsComponent } from '...' statement in the routes file. The bundler includes it in the main chunk, defeating lazy loading. import { Settings } from './settings'; { path: 'settings', component: Settings } { path: 'settings', loadComponent: () => import('./settings').then(m => m.Settings) }
Using component instead of loadComponent Specifying component on a route instead of loadComponent. This always eagerly loads the component. { path: 'x', component: XComponent } { path: 'x', loadComponent: () => import('...') }

11. Best Practices

  • Lazy-load feature areas: Group related functionality (like an admin panel or user settings area) into separate route files and use loadChildren to load the entire group on demand.
  • Use PreloadAllModules for critical routes: Enable the PreloadAllModules strategy to download lazy-loaded chunks in the background after the initial page renders, improving navigation speed for subsequent routes.
  • Avoid standard imports of lazy components: Never use a top-level import statement for components or route files that should be lazy-loaded. Only reference them inside the dynamic import() expression.

12. Browser Compatibility/Requirements

Lazy loading uses dynamic import() expressions, which are supported in all modern browsers. The Angular CLI build process handles code splitting automatically during compilation.

13. Interview Questions

Q1: What is the difference between loadComponent and loadChildren in Angular routing?

Answer: loadComponent lazy-loads a single standalone component for one route. loadChildren lazy-loads an entire child routes configuration (an array of route definitions), which is ideal for feature areas with multiple nested routes that should all be split into a single chunk.

Q2: How do you verify that lazy loading is working correctly?

Answer: Run the production build (ng build) and inspect the output directory. Lazy-loaded routes should produce separate chunk files (e.g. chunk-XXXX.js). You can also open the browser Network tab and observe that separate JavaScript files are downloaded on-demand when navigating to lazy-loaded routes.

14. Debugging Exercise

The settings component is supposed to be lazy-loaded, but it always appears in the main bundle. Identify the bug:

View Solution

Diagnosis: Line 1 contains a standard top-level import statement for SettingsComponent. Even though the route uses loadComponent with a dynamic import, the static import on Line 1 forces the bundler to include the component in the main chunk. The dynamic import becomes redundant.

Fix: Remove the static import statement on Line 1. Only reference the component inside the dynamic import() expression.

15. Practice Exercises

Exercise 1: Implement feature-level lazy loading

Create a "Reports" feature area with three child routes (Overview, Sales, Inventory). Use loadChildren to lazy-load the entire feature area. Enable PreloadAllModules and verify the chunk files are preloaded after initial render using the browser Network tab.

16. Scenario-Based Challenge

The Performance Optimization Challenge:

An Angular application has a main bundle size of 2.5 MB. The app contains feature areas for Products, Orders, Admin, and Analytics. Only the Home page is visited on the first load. Redesign the route configuration to lazy-load all feature areas and implement a custom preloading strategy that only preloads routes marked with data: { preload: true }.

17. Quick Quiz

Q1: Which route property should you use to lazy-load a single standalone component?

A) component

B) loadChildren

C) loadComponent

Answer: C — The loadComponent property uses a dynamic import to lazy-load a single standalone component.

18. Summary & Key Takeaways

  • Lazy loading splits application code into separate chunks downloaded on-demand, improving initial load performance.
  • Use loadComponent for single standalone components and loadChildren for multi-route feature areas.
  • Never use static top-level import statements for lazy-loaded components.
  • Enable PreloadAllModules to preload lazy chunks in the background after initial render.

19. Cheat Sheet

API Purpose
loadComponent Lazy-loads a single standalone component via dynamic import.
loadChildren Lazy-loads a child routes configuration via dynamic import.
withPreloading(PreloadAllModules) Preloads all lazy chunks in the background after initial render.
---