Angular Performance: Change Detection and OnPush Explained
Most Angular performance problems aren't the framework — they're change detection running far more often than it needs to.
By default, Angular re-checks every component in the tree on nearly every asynchronous event: a click, a timer, an HTTP response. For small apps that's invisible. In a large dashboard with hundreds of bindings, it becomes the reason the UI feels sluggish.
Understand what triggers a check
Angular's default strategy runs a full tree check whenever Zone.js sees an async task complete. You can't eliminate that, but you can make each component cheap to check — or skip it entirely.
Switch to OnPush
ChangeDetectionStrategy.OnPush tells Angular to check a component only when its inputs change by reference, an event fires from within it, or an observable it subscribes to (via the async pipe) emits.
@Component({
selector: 'app-metric-card',
templateUrl: './metric-card.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MetricCardComponent {
@Input() metric!: Metric;
}
Keep data immutable
OnPush compares input values by reference, so mutating an object in place won't trigger a re-render. Create new objects instead:
// Won't update the view
this.user.name = 'Ayesha';
// Will update the view
this.user = { ...this.user, name: 'Ayesha' };
Use trackBy in lists
Without a stable identity, Angular recreates DOM nodes when a list changes. A track function lets it reuse them:
@for (user of users; track user.id) {
<app-user-row [user]="user" />
}
Avoid function calls and getters in templates
{{ computeTotal() }} runs on every change detection cycle. Compute the value once, store it in a field, and update it when the underlying data changes. The same applies to heavy pipes — use a pure pipe or precompute.
The result
OnPush plus immutable updates typically removes the majority of unnecessary checks. Combined with list tracking and precomputed values, large Angular screens stay responsive without micro-optimising every template.
Back to all articles