Angular DevTools Profiler
The Angular DevTools profiler records component refresh times during interactions, helping you find performance bottlenecks.
Installing Angular DevTools
- Install the Angular DevTools browser extension (Chrome/Firefox)
- Open your Angular app in the browser
- Open DevTools → Angular tab
- Click the "Record" button
- Interact with your app
- 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?
2. What is a common cause of slow change detection?
3. What is the benefit of OnPush on leaf components?
Flashcards
Question
What does the profiler do?
Click to reveal answer
Answer
Records component refresh times. Shows flame graph of slow components.
Question
Common cause of slow detection?
Click to reveal answer
Answer
Expensive template expressions evaluated every change detection cycle.
Question
Benefit of OnPush on leaf components?
Click to reveal answer
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:
- Install browser extension
- Open Angular tab
- Record interactions
- 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