0
0
AngularHow-ToBeginner · 4 min read

How to Optimize Angular App Performance: Best Practices

To optimize an Angular app's performance, use OnPush change detection to reduce unnecessary checks, implement lazy loading for modules to load code only when needed, and use trackBy in *ngFor to efficiently update lists. These techniques reduce rendering work and improve app speed.
📐

Syntax

Here are key Angular syntax patterns to optimize performance:

  • OnPush Change Detection: Use changeDetection: ChangeDetectionStrategy.OnPush in component decorator to limit checks.
  • Lazy Loading Modules: Use Angular Router's loadChildren to load modules only when routes are accessed.
  • trackBy in *ngFor: Add trackBy function to *ngFor to identify items uniquely and avoid full list re-render.
typescript
import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleComponent {
  items = [/* array of items */];

  trackById(index: number, item: any): number {
    return item.id;
  }
}
💻

Example

This example shows a component using OnPush change detection and trackBy in *ngFor to optimize rendering of a list.

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

@Component({
  selector: 'app-item-list',
  template: `
    <ul>
      <li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>
    </ul>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ItemListComponent {
  items = [
    { id: 1, name: 'Apple' },
    { id: 2, name: 'Banana' },
    { id: 3, name: 'Cherry' }
  ];

  trackById(index: number, item: any): number {
    return item.id;
  }
}
Output
<ul><li>Apple</li><li>Banana</li><li>Cherry</li></ul>
⚠️

Common Pitfalls

Common mistakes that hurt Angular app performance include:

  • Using default ChangeDetectionStrategy.Default which runs checks on every event.
  • Not using trackBy in *ngFor, causing Angular to recreate all DOM elements on list changes.
  • Loading all modules eagerly instead of lazy loading, increasing initial load time.

Fixing these improves speed and responsiveness.

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

/* Wrong: No trackBy, default change detection */
@Component({
  selector: 'app-list',
  template: `
    <li *ngFor="let item of items">{{ item.name }}</li>
  `
})
export class ListComponent {
  items = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }];
}

/* Right: Use trackBy and OnPush */
@Component({
  selector: 'app-list',
  template: `
    <li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ListComponent {
  items = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }];

  trackById(index: number, item: any): number {
    return item.id;
  }
}
📊

Quick Reference

  • Use OnPush Change Detection: Limits checks to input changes.
  • Implement Lazy Loading: Load modules only when needed via router.
  • Use trackBy in *ngFor: Prevents unnecessary DOM updates.
  • Avoid heavy computations in templates: Move logic to component code.
  • Use Pure Pipes: For efficient data transformations.

Key Takeaways

Use OnPush change detection to reduce unnecessary component checks.
Implement lazy loading to decrease initial app load time.
Always use trackBy with *ngFor to optimize list rendering.
Avoid complex logic in templates to improve rendering speed.
Use pure pipes for efficient data transformations.