If you’ve ever worked on a large Angular app that suddenly felt sluggish when users started clicking around, chances are the problem was tied to change detection.
Angular is smart, but out of the box, it loves to check everything all the time. That’s not always bad, but if you’ve got hundreds of components flying around, your CPU is going to scream.
This is where the Change Detection Strategy in Angular comes in. It basically controls when Angular updates your UI and how often it re-renders things. Picking the right one can give your app a noticeable performance boost without rewriting half your codebase.
Let’s break it down in plain English, with real examples and a few pro tips from the trenches.
What Is the Change Detection Strategy in Angular?
Change detection is Angular’s way of asking: “Do I need to update the DOM right now?”
Every time something changes in your app—maybe an input box, a button click, or a new API response—Angular decides whether it should re-check components. The Change Detection Strategy defines the rules for this process..

Angular ships with two strategies:
- Default (CheckAlways) – Angular checks all components whenever anything changes.
- OnPush (CheckOnce) – Angular only checks a component when a specific trigger happens.
Used correctly, this can be the difference between a smooth dashboard and one that lags every time you type.
👉 Pro Tip: If you’re curious about how this plays with RxJS, check out the Async Pipe in Angular. It’s like change detection’s best friend when working with observables.
Default Strategy (CheckAlways
)
Description:
This is Angular’s out-of-the-box behavior. If you don’t configure anything, Angular assumes you want this strategy.
How It Works:
Angular checks every single component on every change event.
Doesn’t care if the component actually needs it—it just runs.
Keeps everything updated, but can get expensive in big apps
Behavior:
- Runs detection on every tick (think user actions, HTTP responses, timers).
- Zero setup, works everywhere.
- Can slow things down once your component tree grows.
Use Case:
Perfect for small to medium apps.
Great if your components update a lot (e.g., chat apps, live dashboards).
Example:
@Component({
selector: 'app-live-chat',
templateUrl: './live-chat.component.html',
// Default detection runs here automatically
})
export class LiveChatComponent {
@Input() messages: string[] = [];
}
I once worked on a chat app where this was a lifesaver because the UI was constantly shifting. But on a larger dashboard with 50+ components, it quickly became a performance hog.
OnPush Strategy (CheckOnce
)
Description:
The OnPush strategy tells Angular: “Stop checking everything all the time. Only re-check me when you really need to.”
How It Works:
Angular will only re-check a component if:
- An
@Input()
property’s reference changes. - An event happens inside the component.
- An observable emits new data.
- You manually poke Angular with
markForCheck()
ordetectChanges()
.
.Behavior:
- Much lighter, because Angular skips unnecessary work.
- Child components also follow OnPush unless you override them.
- Best paired with immutable data patterns.
Use Case:
Large apps where you don’t want every click to trigger a cascade of checks.
Components that rarely change (think: product cards, profile blocks).
Example:
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProductListComponent {
@Input() products: Product[];
// Angular only checks when products input reference changes
}
I once swapped a Default strategy for OnPush in a product dashboard, and the app’s “jank” disappeared overnight. The DOM only updated when fresh data came in—not on every keypress or random timer.
🔗 Related: Angular 16 – performance optimizations in newer Angular versions make OnPush even more effective.
How to Set Change Detection Strategy in Angular
Adding OnPush is as simple as a single line in your component decorator:
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ExampleComponent {}
That one line can shave off milliseconds on each tick—which adds up fast in a big app.
👉 If you’re still wrapping your head around Angular’s lifecycle, the AfterViewInit Guide might help put things in perspective.
OnPush vs Default: Side-by-Side
Here’s a quick snapshot:
Feature | Default (CheckAlways) | OnPush (CheckOnce) |
---|---|---|
Trigger | Every Angular event | Input change / event / observable |
Performance | Slower at scale | Faster, efficient |
Manual Control | Not needed | Sometimes required |
Best For | Dynamic, fast-changing UIs | Static or input-driven UIs |
When Should You Use OnPush?
Go with OnPush if:
- You’re working with immutable data.
- Your app is large and has many components.
- Updates are infrequent or predictable.
Stick with Default if:
- You’re building smaller apps.
- Your components rely on mutable data.
- You don’t want to micromanage change detection.
💡 Tooling Tip: Fire up Angular DevTools and watch how often change detection runs. It’s eye-opening—and usually convinces devs to switch to OnPush at least in some places.
Real-World Example
Imagine a product dashboard where new products only load in when an API response arrives. You don’t want Angular constantly refreshing the entire component tree for no reason.
@Component({
selector: 'app-product-dashboard',
templateUrl: './product-dashboard.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProductDashboardComponent {
@Input() products: Product[];
}
Here, Angular updates only when the products
input reference changes—exactly when you’d expect. Smooth, predictable, efficient.
🔗 Related: Organizing Types and Interfaces in Your TypeScript Project – a clean data model works beautifully with OnPush and immutability.
Final Thoughts: Choosing the Right Change Detection Strategy in Angular
The Change Detection Strategy in Angular is one of those features you don’t think about until your app starts lagging.
- Default works fine for small or frequently changing apps.
- OnPush excels in large-scale applications where efficiency is crucial.
The trick is knowing when to switch. Use DevTools, watch your component tree, and don’t be afraid to experiment.
At the end of the day, the right strategy keeps your Angular apps feeling snappy—and your users happy.
Leave a Reply