Skip to content
advanced Phase 15 · Performance Optimization and Lazy Loading

Profiling Change Detection

Find components that re-render too often during interactions.

45m
0 problems
Topic Progress 0%

Angular DevTools Profiler

The Angular DevTools profiler records component refresh times during interactions, helping you find performance bottlenecks.

Installing Angular DevTools

  1. Install the Angular DevTools browser extension (Chrome/Firefox)
  2. Open your Angular app in the browser
  3. Open DevTools → Angular tab
  4. Click the "Record" button
  5. Interact with your app
  6. Stop recording and analyze the flame graph

Reading the Profiler Output

Component Tree          |  Refresh Time
------------------------|---------------
AppComponent            |  0.1ms
├── HeaderComponent     |  0.05ms
├── ProductListComponent |  15.3ms  ← Problem!
│   ├── ProductCard     |  2.1ms
│   ├── ProductCard     |  2.0ms
│   └── ...
└── FooterComponent      |  0.02ms

Long bars indicate components that take too long to refresh.

Common Performance Issues

Issue Solution
Expensive template expressions Move to pure pipes or signals
Deep component trees with default detection Use OnPush
Large lists without trackBy Add trackBy
Frequent change detection cycles Use signals for fine-grained updates
Heavy computations in ngOnInit Move to lazy loading or web workers

Optimization Strategies

Once you identify bottlenecks, apply targeted optimizations.

Move Computation to Signals

// BAD: Expensive computation in template
@Component({
  template: `
    <p>{{ expensiveFilter(items).length }} items</p>
  `,
})
export class MyComponent {
  items = [...];

  expensiveFilter(items: Item[]): Item[] {
    return items.filter(i => i.active).map(i => i.name);
  }
}

// GOOD: Computed signal
@Component({
  template: `
    <p>{{ activeItemCount() }} items</p>
  `,
})
export class MyComponent {
  items = signal<Item[]>([]);

  activeItemCount = computed(() =>
    this.items().filter(i => i.active).length
  );
}

Apply OnPush to Leaf Components

@Component({
  selector: 'app-product-card',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `<p>{{ product.name }}</p>`,
})
export class ProductCardComponent {
  @Input() product!: Product;
}

Use Pure Pipes

@Pipe({ name: 'filterActive', pure: true, standalone: true })
export class FilterActivePipe implements PipeTransform {
  transform(items: Item[]): Item[] {
    return items.filter(i => i.isActive);
  }
}

Performance Checklist

  • OnPush on leaf components
  • trackBy on all *ngFor/@for loops
  • Computed signals instead of template expressions
  • Pure pipes for transformations
  • Lazy loading for feature routes
  • @defer for heavy template content
  • No expensive operations in ngOnInit

Quiz

1. What does the Angular DevTools profiler do?

Question 1 options

2. What is a common cause of slow change detection?

Question 2 options

3. What is the benefit of OnPush on leaf components?

Question 3 options

Flashcards

Question

What does the profiler do?

Answer

Records component refresh times. Shows flame graph of slow components.

Question

Common cause of slow detection?

Answer

Expensive template expressions evaluated every change detection cycle.

Question

Benefit of OnPush on leaf components?

Answer

Skip detection unless inputs/signals/events change.

Revision Notes

Key Takeaways

  • 1. Angular DevTools profiler shows component refresh times
  • 2. Expensive template expressions are a common bottleneck
  • 3. OnPush skips unnecessary change detection
  • 4. Move computation to signals or pure pipes

Interview Tips

  • • Explain how to use the Angular DevTools profiler
  • • Be ready to describe common performance issues
  • • Mention OnPush and signals as optimization strategies

Cheat Sheet

Profiling Change Detection Cheat Sheet

Angular DevTools:

  1. Install browser extension
  2. Open Angular tab
  3. Record interactions
  4. Analyze flame graph

Optimizations:

  • OnPush on leaf components
  • trackBy on all lists
  • Computed signals for derived state
  • Pure pipes for transformations
  • @defer for heavy content

Continue Learning