When building large Angular applications, managing routes and performance becomes crucial. Angular’s Routing, Lazy Loading, and Route Guards make this task much easier and efficient. Let’s explore these concepts step-by-step in simple language.
🧭 What is Angular Routing?
Routing in Angular helps you navigate between different views (components) in a single-page application (SPA).
Instead of loading a new HTML page every time, Angular dynamically updates the view using routes.
Example
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'products', component: ProductListComponent },
{ path: 'contact', component: ContactComponent }
];
Here:
/ → Home page
/products → Product list
/contact → Contact page
You link these routes in your HTML using the Angular router:
<a routerLink="/products">Products</a>
And render them inside your main layout:
<router-outlet></router-outlet>
🚀 What is Lazy Loading?
As your Angular app grows, you may have many modules — Products, Orders, Customers, Reports, etc.
If you load all modules at once, the initial load time increases. Lazy Loading helps by loading modules only when needed.
🔹 Without Lazy Loading
All modules are loaded when the app starts — even if the user doesn’t visit them.
🔹 With Lazy Loading
Modules load only when the user navigates to them — improving performance and user experience.
Example
const routes: Routes = [
{ path: '', component: DashboardComponent },
{ path: 'products', loadChildren: () => import('./products/products.module').then(m => m.ProductsModule) },
{ path: 'orders', loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule) }
];
This means
🧠 Flowchart: How Lazy Loading Works
┌────────────────────┐
│ User Opens App │
└────────┬───────────┘
│
▼
┌────────────────────┐
│ Root Module Loads │
└────────┬───────────┘
│
┌───────────▼─────────────┐
│ User Clicks “Products” │
└───────────┬─────────────┘
│
▼
┌────────────────────┐
│ Angular loads │
│ ProductsModule │
└────────────────────┘
This flow keeps your main app lightweight and fast.
🛡️ What are Route Guards?
Route Guards protect routes based on conditions.
They prevent unauthorized or incorrect navigation — just like a security gate in your app.
Angular provides five types of guards:
| Guard Type | Purpose |
|---|
| CanActivate | Prevents unauthorized access to a route |
| CanDeactivate | Stops navigation if form changes are unsaved |
| Resolve | Fetches data before loading the route |
| CanLoad | Stops lazy-loaded modules from loading without permission |
| CanActivateChild | Protects child routes |
Example: CanActivate Guard
auth.guard.ts
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
In routes
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }
Now, only logged-in users can access /dashboard.
⚙️ Combine Lazy Loading + Route Guards
You can apply guards to lazy-loaded modules too.
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [AuthGuard]
}
This ensures the AdminModule won’t even load unless the user is authorized.
🧩 Best Practices
✅ Always lazy load feature modules in large apps.
✅ Use route guards for authentication and data safety.
✅ Keep routing modules modular (one per feature).
✅ Preload critical modules using Angular’s PreloadAllModules strategy.
✅ Avoid deeply nested routes for better readability.
🏁 Conclusion
Routing is the backbone of every Angular application. By combining Lazy Loading and Route Guards, you can make your apps faster, secure, and more maintainable.
Next time you build a large Angular project — remember: Load smart, guard smart!