TL;DR
- Lazy loading in Angular improves initial load speed by splitting your app into smaller chunks.
- Use
loadChildren
for lazy-loading modules; useloadComponent
for standalone components. - Standalone components cut boilerplate and simplify route configuration.
- Keep each lazy-loaded feature in its own folder for clarity and maintainability.
- Preloading strategies optimize navigation speed after the first load.
- Prefer standalone components for new features; use modules when grouping multiple related components.
Ever notice how your Angular app feels sluggish on first load? That’s probably because you’re loading everything upfront. Lazy loading fixes this by splitting your app into chunks that load only when users actually need them.
Instead of downloading your entire app at once, lazy loading lets you load features on-demand. User clicks “Admin Panel”? That’s when the admin code downloads. Much faster initial loads, happier users.
Angular 19 gives you two ways to lazy load: the traditional module approach and the newer standalone component approach. Let’s see both in action.
Module-Based Lazy Loading
Here’s the classic approach using feature modules:
// app.routes.ts
import { Routes } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) },
{ path: '**', redirectTo: '/home' }
];
// home/home.module.ts
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HomeComponent } from './home.component';
@NgModule({
declarations: [HomeComponent],
imports: [
RouterModule.forChild([
{ path: '', component: HomeComponent } // Child route within the module
])
]
})
export class HomeModule { }
Standalone Component Lazy Loading
Now here’s the modern approach with standalone components:
// app.routes.ts
import { Routes } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadComponent: () => import('./home/home.component').then(c => c.HomeComponent) },
{ path: 'admin', loadComponent: () => import('./admin/admin.component').then(c => c.AdminComponent) },
{ path: '**', redirectTo: '/home' }
];
// home/home.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-home',
standalone: true, // This makes it a standalone component
imports: [CommonModule], // Import dependencies directly
template: `<h1>Welcome Home!</h1>`
})
export class HomeComponent { }
Notice how much cleaner the standalone approach is? No module boilerplate, direct imports, and the routing config is simpler.
Key Differences
Module-Based | Standalone Component |
---|---|
Uses loadChildren | Uses loadComponent |
Requires feature modules | No modules needed |
Child routes defined in module | Routes defined directly in main config |
More boilerplate | Cleaner, less code |
Good for complex features | Perfect for simple routes |
Folder Structure Tips
Keep your lazy-loaded features organized:
src/app/
├── home/
│ ├── home.component.ts
│ └── home.component.html
├── admin/
│ ├── admin.component.ts
│ └── admin.component.html
└── app.routes.ts
Pro tip: Angular’s CLI generates standalone components by default now, so ng generate component admin
will create a standalone component ready for lazy loading.
Default Behavior
Angular uses “lazy by default” behavior, routes only load when accessed. But you can add preloading strategies if you want:
// main.ts
bootstrapApplication(AppComponent, {
providers: [
provideRouter(routes, withPreloading(PreloadAllModules)) // Preload after initial load
]
});
When to Choose What
Go with standalone components for most new features. They’re simpler, have less boilerplate, and work great for straightforward routes.
Stick with modules when you have complex features that need multiple components, services, and guards working together. Modules still make sense for large, self-contained feature areas.
The bottom line? Lazy loading dramatically improves your app’s startup time. Standalone components make it even easier to implement. Start with loadComponent
for new features, your users will notice the performance boost immediately.
Frequently Asked Questions
What is lazy loading in Angular and why is it important?
How do you implement lazy loading with Angular modules?
Lazy loading with modules uses the loadChildren
property in route configuration. For example:
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
This loads the AdminModule
only when the user navigates to the /admin
route.
What are standalone components in Angular 19?
How do you lazy load a standalone component in Angular?
Use the loadComponent
property in your route configuration. For example:
{ path: 'home', loadComponent: () => import('./home/home.component').then(c => c.HomeComponent) }
This loads the HomeComponent
only when the /home
route is accessed.
What are the main differences between module-based and standalone component lazy loading?
loadChildren
and requires feature modules, while standalone component lazy loading uses loadComponent
and does not require modules. Standalone components reduce boilerplate and are better for simple routes, while modules are useful for complex features with multiple dependencies.When should you use modules instead of standalone components for lazy loading?
How does Angular’s default lazy loading behavior work?
What is a preloading strategy in Angular and how do you use it?
A preloading strategy loads lazy routes in the background after the initial app load, improving perceived navigation speed. You can enable it with:
provideRouter(routes, withPreloading(PreloadAllModules))
This preloads all lazy-loaded modules after the app starts.
How should you organize folders for lazy-loaded features in Angular?
Place each lazy-loaded feature in its own folder under src/app/
, keeping related components, templates, and styles together. For example:
src/app/
├── home/
├── admin/
└── app.routes.ts