Performance Optimization in Angular - Textnotes

Performance Optimization in Angular


Optimizing performance in Angular ensures fast loading, smooth UI, and better user experience, especially in large-scale applications. Angular provides multiple techniques to improve performance.

1. ChangeDetectionStrategy.OnPush

By default, Angular runs change detection on every event. OnPush strategy only checks when input properties change or events occur inside the component.


import { Component, ChangeDetectionStrategy, Input } from '@angular/core';

@Component({
selector: 'app-user',
template: `<p>{{ user.name }}</p>`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserComponent {
@Input() user: any;
}
  1. Reduces unnecessary DOM checks
  2. Improves performance for large component trees

*2. trackBy in ngFor

Use trackBy to optimize *ngFor loops. Angular can reuse DOM elements instead of recreating them.


<li *ngFor="let user of users; trackBy: trackById">
{{ user.name }}
</li>

trackById(index: number, user: any) {
return user.id;
}
  1. Helps when dealing with large arrays
  2. Minimizes DOM manipulation

3. Lazy Loading

Load feature modules only when needed:


{ path: 'users', loadChildren: () => import('./users/users.module').then(m => m.UsersModule) }
  1. Reduces initial bundle size
  2. Improves app startup time

4. Preloading Strategies

Preload lazy-loaded modules in the background to improve navigation speed:


RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  1. Loads modules after initial app load
  2. Balances performance and user experience

5. Optimizing Bundle Size

  1. Use Angular CLI production build:

ng build --prod
  1. Enable AOT compilation
  2. Remove unused modules and libraries
  3. Use lazy loading and tree-shaking
  4. Compress assets with gzip or Brotli

6. Caching with Interceptors

Use HTTP interceptors to cache API responses and reduce redundant requests:


import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class CacheInterceptor implements HttpInterceptor {
private cache = new Map<string, any>();

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.method !== 'GET') return next.handle(req);

const cachedResponse = this.cache.get(req.url);
if (cachedResponse) return of(cachedResponse);

return next.handle(req).pipe(
tap(event => this.cache.set(req.url, event))
);
}
}
  1. Reduces network calls
  2. Improves response time

Summary

  1. Use ChangeDetectionStrategy.OnPush to reduce unnecessary checks.
  2. Apply trackBy in *ngFor for efficient DOM updates.
  3. Implement lazy loading to reduce initial bundle size.
  4. Use preloading strategies to improve navigation performance.
  5. Optimize bundle size with AOT, tree-shaking, and lazy loading.
  6. Cache API responses using HTTP interceptors to reduce network calls.