Angular Performance Optimization
Master Angular performance with lazy loading, change detection strategies, AOT compilation, and modern optimization techniques.
Angular Performance Challenges
Angular is a powerful framework, but its comprehensive nature can lead to performance bottlenecks if not configured properly. Key areas include change detection, bundle size, lazy loading, and compilation strategy. Modern Angular (v14+) includes significant performance improvements, but understanding optimization techniques is crucial.
Lazy Loading
Load modules on-demand to reduce initial bundle size.
Change Detection
Optimize Angular's change detection for better runtime performance.
AOT Compilation
Ahead-of-Time compilation for faster startup and smaller bundles.
Tree-Shaking
Remove unused code with proper imports and Ivy renderer.
1. Implement Lazy Loading
Reduce initial bundle size by loading modules only when needed:
Route-Based Lazy Loading
// app-routing.module.tsimport { NgModule } from '@angular/core';import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [ { path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.module') .then(m => m.DashboardModule) }, { path: 'admin', loadChildren: () => import('./admin/admin.module') .then(m => m.AdminModule) }];
@NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule]})export class AppRoutingModule { }Standalone Components (Angular 14+)
// Lazy load standalone componentsconst routes: Routes = [ { path: 'dashboard', loadComponent: () => import('./dashboard/dashboard.component') .then(m => m.DashboardComponent) }];Preloading Strategy
// Preload modules after initial loadimport { PreloadAllModules } from '@angular/router';
@NgModule({ imports: [ RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) ]})2. Optimize Change Detection
Angular's change detection can be expensive. Optimize it for better performance:
OnPush Change Detection Strategy
import { Component, ChangeDetectionStrategy, Input } from '@angular/core';
@Component({ selector: 'app-user-card', templateUrl: './user-card.component.html', changeDetection: ChangeDetectionStrategy.OnPush})export class UserCardComponent { @Input() user: User;}Manual Change Detection
import { Component, ChangeDetectorRef } from '@angular/core';
export class MyComponent { constructor(private cdr: ChangeDetectorRef) {}
updateData(data: any) { this.data = data; // Manually trigger change detection this.cdr.markForCheck(); }
// Detach from change detection for expensive operations performExpensiveOperation() { this.cdr.detach(); // ... expensive work this.cdr.reattach(); }}TrackBy for ngFor
<!-- Without trackBy (slow) --><div *ngFor="let item of items">{{ item.name }}</div>
<!-- With trackBy (fast) --><div *ngFor="let item of items; trackBy: trackByFn"> {{ item.name }}</div>
// ComponenttrackByFn(index: number, item: any): any { return item.id; // unique identifier}3. Enable AOT Compilation
Ahead-of-Time compilation improves startup performance:
Production Build Configuration
// angular.json{ "projects": { "my-app": { "architect": { "build": { "configurations": { "production": { "optimization": true, "outputHashing": "all", "sourceMap": false, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true } } } } } }}Build Command
# Production build with AOTng build --configuration=production
# Analyze bundle sizenpm install -g webpack-bundle-analyzerng build --stats-jsonwebpack-bundle-analyzer dist/my-app/stats.json4. Optimize Bundle Size
Reduce JavaScript bundle size for faster downloads:
Tree-Shakable Providers
// Use providedIn for tree-shakable servicesimport { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' // Tree-shakable})export class MyService { }Import Only What You Need
// Bad - imports entire moduleimport * as moment from 'moment';
// Good - import only what you needimport { format } from 'date-fns';
// Even better - use Angular's DatePipe{{ date | date:'short' }}Differential Loading
// tsconfig.json - Modern browsers get smaller bundles{ "compilerOptions": { "target": "ES2020", "module": "ES2020" }}5. Optimize Templates and Pipes
Improve runtime performance with template optimizations:
Pure Pipes
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'exponential', pure: true // Only recompute when input changes})export class ExponentialPipe implements PipeTransform { transform(value: number, exponent = 1): number { return Math.pow(value, exponent); }}Avoid Function Calls in Templates
<!-- Bad - function called every change detection --><div>{{ calculateTotal() }}</div>
<!-- Good - use computed property or pipe --><div>{{ total }}</div>
// Componentget total() { return this.items.reduce((sum, item) => sum + item.price, 0);}Use ng-container
<!-- Don't add extra DOM nodes --><ng-container *ngIf="user"> <div>{{ user.name }}</div> <div>{{ user.email }}</div></ng-container>6. Image and Asset Optimization
Optimize images with Angular's Image directive (v15+):
NgOptimizedImage
import { NgOptimizedImage } from '@angular/common';
@Component({ imports: [NgOptimizedImage], template: ` <img ngSrc="hero.jpg" width="800" height="600" priority alt="Hero image" /> `})Lazy Loading Images
<img ngSrc="below-fold.jpg" width="400" height="300" loading="lazy" alt="Below fold image"/>7. Runtime Performance
Additional runtime optimizations:
- •Use Web Workers for CPU-intensive tasks
- •Implement virtual scrolling with
@angular/cdk/scrolling - •Use RxJS operators to avoid memory leaks (unsubscribe)
- •Implement service worker for offline support and caching
- •Use Angular DevTools to profile component performance
Analyze Your Angular App
Get Angular-specific optimization recommendations powered by AI.
Test Your Angular Site