ChangeDetectionStrategy.OnPush

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! ⚡

angular #typescript #signals #frontend #architecture