OnPush Change Detection Strategy: Optimizing Angular Performance

Angular applications often need to manage complex data binding and frequent updates, which can lead to performance issues if not handled properly. One powerful technique to optimize performance is using the OnPush change detection strategy. This article explores what OnPush is, how it works, and provides practical examples to help you implement it in your Angular projects.

What is OnPush change detection?

By default, Angular uses the Default change detection strategy, where every component checks for changes whenever an event occurs, such as user input, HTTP requests, or timers. This can lead to performance bottlenecks, especially in large applications.

OnPush change detection strategy improves performance by checking for changes only when:

  1. The component's input properties change.
  2. An event is triggered within the component.

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

  1. Improved Performance: Reduces unnecessary checks, leading to better performance.
  2. Predictable Change Detection: This makes it easier to reason about when and why Angular checks for changes.
  3. 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.


Similar Articles