Published: November 15, 2021
Introduction
Change detection in Angular is a fundamental concept that impacts how your application updates the UI in response to data changes. Understanding how Angular’s Change Detection Strategy works is crucial for building high-performance applications.
In this post, we’ll explore:
- The basics of Angular’s default change detection mechanism
- How
ChangeDetectionStrategy.OnPush
changes the game - When to use OnPush and why it improves rendering performance
- Practical examples illustrating both strategies
Angular’s Default Change Detection
By default, Angular uses the Default change detection strategy. This means:
- Every time Angular runs change detection (e.g., user input, HTTP responses, timers), it checks every component in the component tree for data changes.
- Angular walks the entire tree and updates any bindings that have changed.
Why is this inefficient sometimes?
In complex or large applications, checking every component frequently—even those whose inputs haven’t changed—can hurt performance.
Enter OnPush: Smarter Change Detection
ChangeDetectionStrategy.OnPush
tells Angular:
Only check this component (and its subtree) when:
- Its @Input() properties change (by reference)
- An event originated from the component or one of its children
- You manually trigger change detection
This means Angular skips checking the component unless it has a clear reason to believe something changed. This reduces unnecessary checks and improves app responsiveness.
How to Use OnPush
Add the changeDetection
property to your component decorator:
import { Component, ChangeDetectionStrategy, Input } from '@angular/core';
@Component({
selector: 'app-user-profile',
template: `
<p>{{ user.name }}</p>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserProfileComponent {
@Input() user!: { name: string };
}
Example: Default vs OnPush
Let’s see a simple demo.
App Component (Parent):
@Component({
selector: 'app-root',
template: `
<button (click)="updateName()">Update Name</button>
<app-user-profile [user]="user"></app-user-profile>
`
})
export class AppComponent {
user = { name: 'Alice' };
updateName() {
// Mutating the property without changing reference
this.user.name = 'Bob';
}
}
UserProfileComponent with Default change detection:
- The template will update even when the
user
object reference remains the same because Angular checks everything every cycle.
UserProfileComponent with OnPush:
- The template will NOT update because the
user
input reference didn’t change (only a property inside it changed).
Fixing OnPush Update Issues
To work correctly with OnPush, immutable data or new object references must be passed.
Modify the updateName
method:
updateName() {
// Create a new object reference
this.user = { ...this.user, name: 'Bob' };
}
Now, OnPush detects the change and updates the UI.
When to Use OnPush
- Your components have immutable inputs or you can guarantee new references when data changes.
- You want to reduce the number of checks Angular performs.
- You’re building a complex UI with many components where performance matters.
- Your app uses push-based state management (e.g., NgRx, RxJS).
Detecting and Manually Triggering Change Detection
Sometimes, you might have to manually trigger change detection (e.g., after an asynchronous event outside Angular’s zone):
import { ChangeDetectorRef } from '@angular/core';
constructor(private cd: ChangeDetectorRef) {}
someAsyncMethod() {
// After async event
this.cd.markForCheck(); // Marks the component to be checked next cycle
// Or
this.cd.detectChanges(); // Immediately runs change detection for this component
}
Summary
Strategy | When It Checks | Performance | Use Case |
---|---|---|---|
Default | Every change detection cycle | Less performant | Small apps, simple UIs |
OnPush | Only when inputs change or events fire | More performant | Complex apps, immutable data |
Switching to OnPush is one of the most effective ways to optimize Angular apps, but it requires disciplined state management.
Further Reading
- Angular Change Detection Explained (Official Docs)
- Understanding OnPush Change Detection
- Immutable Data Patterns in Angular
Ready to boost your Angular app’s performance? Try switching key components to OnPush today!