In Angular 19, performance and reactivity have reached new heights with the maturity of Signals, standalone components, and the continued use of ChangeDetectionStrategy.OnPush
. But how does OnPush
actually work—and why is it more powerful than ever in Angular 19?
Let’s break it down.
What Is Change Detection in Angular?
Change detection is Angular’s internal mechanism to keep your UI in sync with your application state.
By default, Angular uses the Default strategy, which:
- Checks every component on each event (clicks, HTTP, setTimeout, etc.)
- May result in unnecessary performance costs as your app scales
ChangeDetectionStrategy.OnPush
import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
selector: 'app-optimized',
templateUrl: './optimized.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class OptimizedComponent {}
This tells Angular:
Only run change detection for this component if:
- An
@Input()
reference changes- An event fires in the component
- You explicitly call
markForCheck()
- A Signal or Observable emits a new value
Angular 19 + Signals = Next-Level Performance
In Angular 19, Signals are stable and fully integrated with change detection.
import { signal } from '@angular/core';
@Component({
selector: 'app-counter',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
template: `
c + 1)">Increment
Count: { count() }
`,
})
export class CounterComponent {
count = signal(0);
}
✔️This works beautifully with OnPush
, and you don’t need to manually trigger change detection.
Benefits of Using OnPush
Benefit | Description |
---|---|
⚡ Fast Rendering | Skips unchanged components |
🧠 Smart Reactivity | Integrates cleanly with signal() , async , and Observables |
🧼 Cleaner Code | Encourages immutability and unidirectional flow |
📦 Efficient App | Reduced computation = better user experience |
Common Pitfalls with OnPush
Pitfall | What Happens |
---|---|
Mutating objects/arrays | No re-render (Angular sees no reference change) |
Forgetting markForCheck()
|
UI appears stuck |
Using @Input() with mutation |
Changes not detected unless ref changes |
❌Bad
this.items().push(newItem); // Mutates in place
✅ Good
this.items.update(prev => [...prev, newItem]); // Creates a new array
When to Use OnPush
- Presentational (dumb) components
- Components relying on Signals or RxJS
- Performance-critical sections of your app
- Any place where data is passed via
@Input()
or reactive streams
Final Thoughts
Angular 19 offers a powerful synergy between Signals and OnPush. When used together, they enable ultra-performant, low-overhead UIs that scale beautifully.
Use ChangeDetectionStrategy.OnPush
in all your stateless or reactive components—especially when you’re using Signals or async
.
Happy coding, and may your trees stay clean and your signals stay sharp! ⚡