Angular apps frequently have to deal with intricate data binding and frequent updates, which, if not done correctly, can cause performance problems. The OnPush change detection mechanism is a potent tool for performance optimization. In order to assist you in integrating OnPush into your Angular projects, this article explains what it is, how it functions, and offers useful examples.

OnPush change detection: what is it?

When an event, such user input, an HTTP request, or a timer, happens, every component in Angular employs the Default change detection technique by default, which involves checking for changes. Performance bottlenecks may result from this, particularly in large applications.

Performance is enhanced by the OnPush change detection approach, which looks for changes only when:

  • The input attributes of the component alter.
  • The component experiences the triggering of an event.

By using OnPush, you can reduce the number of checks Angular performs, making your application more efficient.
Implementing OnPush change detection

To implement the OnPush strategy, you need to modify the ChangeDetectionStrategy property of your component's decorator. Here's how you can do it:

Step 1. Import ChangeDetectionStrategy and ChangeDetectorRef
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';

Step 2. Set ChangeDetectionStrategy to OnPush
@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleComponent {
  constructor(private cdr: ChangeDetectorRef) {}
  // Component logic here
}


Step 3. Manage Component Updates
Since OnPush only checks for changes when inputs change, or events occur, you need to handle updates explicitly. For instance, if you update a component's state based on an asynchronous operation, you should manually mark the component for check:
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleComponent {
  data: any;

  constructor(private cdr: ChangeDetectorRef) {}

  updateData(newData: any) {
    this.data = newData;
    this.cdr.markForCheck(); // Explicitly mark for check
  }
}


Practical Example
Here's a complete example demonstrating the OnPush strategy
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, Input, OnInit } from '@angular/core';
@Component({
  selector: 'app-example',
  template: `
    <div>
      <h1>{{title}}</h1>
      <button (click)="fetchData()">Fetch Data</button>
      <p *ngIf="data">{{data}}</p>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExampleComponent implements OnInit {
  @Input() title: string;
  data: string;
  constructor(private cdr: ChangeDetectorRef) {}
  ngOnInit(): void {
    // Initialization logic here
  }
  fetchData(): void {
    // Simulate an async operation
    setTimeout(() => {
      this.data = 'New Data Loaded';
      this.cdr.markForCheck(); // Explicitly mark for check
    }, 2000);
  }
}


Benefits of OnPush Change Detection

  • Improved Performance: Reduces unnecessary checks, leading to better performance.
  • Predictable Change Detection: This makes it easier to reason about when and why Angular checks for changes.
  • Efficient Resource Usage: Decreases CPU usage and enhances overall application responsiveness.

Conclusion
Using the OnPush change detection strategy in Angular is a powerful way to optimize your application's performance. By explicitly managing when Angular checks for changes, you can ensure that your application runs more efficiently, especially as it grows in complexity. Implement OnPush in your Angular projects today to experience these performance benefits firsthand.