Angular: Understanding change detection

Understanding change detection

The secret sauce to Angular’s reactivity and performance is in its change detection strategies and the creative application of those strategies. Change detection is an important mechanism for ensuring the application view stays in sync with the underlying data models, and can respond appropriately when there are changes to these data models.

Disclaimer: Angular has introduced changes to its change detection mechanism in versions 16 and 17.

Change Detection Strategies in Angular

Whenever data changes, Angular needs to reflect those changes in the view. This process involves checking the current value of a templates’ expressions against their previous values. If any differences are detected, Angular updates the view accordingly with the new values.

Angular implements two primary strategies for change detection:

  1. Default (CheckAlways): Angular checks for changes in bindings during every component tree check, starting from the root component down to child components.
  2. OnPush: Angular performs change detection only on components that have received new reference types, or when explicitly triggered.

Example: Default Change Detection Strategy

Let’s illustrate the default change detection with a simple component:


import { Component } from '@angular/core';

@Component({
  selector: 'app-change-detection-example',
  template: `<p>{{counter}}</p>
             <button (click)="increment()">Increment</button>`
})
export class AppComponent {
  counter = 0;

  increment() {
    this.counter++;
  }
}

In this example, every click on the “Increment” button calls the increment method, which updates the counter property. Angular will periodically run a change detection cycle and will detect that this variable has been changed, it will then update the paragraph text in the view with the new counter value.

Similarly let’s illustrate the OnPush change detection strategy with a similar component that also displays a counter. This component will only update its view when the counter property, marked as an input, receives a new value.


import { Component, Input, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-onpush-example',
  template: `<p>Counter: {{counter}}</p>`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CounterDisplayComponent {
  @Input() counter: number;
}

By setting the changeDetection strategy to OnPush, this component optimizes performance by limiting change detection runs. Angular will only update the view for this component when the counter input changes, rather than checking for changes with every interaction or change detection cycle in the application. This approach is particularly useful for components that rely on inputs and do not change frequently, as it helps to minimize unnecessary rendering and improve app performance.

Conclusion

Angular’s change detection mechanism is a fundamental aspect of the framework, ensuring that applications are both reactive and performant.

Attribution

Image by rawpixel.com on Freepik

Leave a Comment

Your email address will not be published. Required fields are marked *