Performance · Common pitfalls
1 min readRapid overview
- Common pitfalls
- 1) Default change detection everywhere
- 2) Overusing Observables for local UI state
- 3) `*ngFor` without `trackBy`
- 4) Heavy logic in templates
- 5) `async` pipe in tight loops (careful)
- 6) Missing cleanup for manual subscriptions
- 7) Running high-frequency events inside Zone
- 8) No virtual scrolling for huge lists
Common pitfalls
1) Default change detection everywhere
Problem: large trees get checked frequently on async events.
Fix:
- prefer
ChangeDetectionStrategy.OnPush - keep inputs immutable (new references)
- use signals for local state/derived values
2) Overusing Observables for local UI state
Problem: extra subscriptions + extra change detection + leak risk.
Fix:
- use signals for local UI toggles/derived values
3) *ngFor without trackBy
Problem: DOM churn and poor scrolling performance.
Fix: trackBy
4) Heavy logic in templates
Problem: template calls run frequently and hide cost.
Fix:
- precompute values (properties)
- use
computed()for derived state
5) async pipe in tight loops (careful)
Problem: multiplying work and re-render churn when used incorrectly.
Fix:
- subscribe/convert once (e.g.,
toSignal) - render from a stable array/value
6) Missing cleanup for manual subscriptions
Fix options:
``ts import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; this.stream$.pipe(takeUntilDestroyed()).subscribe(); ``
- prefer
asyncpipe takeUntilDestroyed()(Angular interop)
7) Running high-frequency events inside Zone
Fix:
ngZone.runOutsideAngular(...)for scroll/market-feed adapters- re-enter the zone only when you need UI updates
8) No virtual scrolling for huge lists
Fix:
cdk-virtual-scroll-viewport(render only what’s visible)