Optimizing Angular Change Detection
ChangeDetectionStrategy.OnPush is a powerful feature in Angular. It lets you precisely control when your components get re-rendered, enhancing your application’s performance. It was a common practice to do extensive data transformations within HTTP services, which ensured that these transformation functions were invoked only once. However, this method required additional optional attributes in data types, which could eventually reduce the readability of the code.
If you prefer using the unsubscribe$ component pattern over the async pipe, you’ll need to use ChangeDetectorRef. This is a tool that allows you to manually tell Angular’s change detection system when there are updates in the component view.
Get Rahul K.’s stories in your inbox
Join Medium for free to get updates from this writer.
ChangeDetectorRef offers two methods:
markForCheck(): This method tells Angular to check this component and its children during the next change detection run. Sometimes, you might notice that your UI doesn't update until a UI event occurs when usingmarkForCheck().detectChanges(): This method triggers change detection immediately. However, frequent usage ofdetectChanges()can cause issues where the view changes after Angular has already checked it.
To address these issues, it seems like a combination of NgZone’s run() method and ChangeDetectorRef's markForCheck() methods might work best.
Here’s a code example to help illustrate this:
import { Component, ChangeDetectorRef, NgZone, ChangeDetectionStrategy } from '@angular/core';
import { Observable } from 'rxjs';
@Component({
selector: 'app-sample',
template: `<div>{{data}}</div>`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SampleComponent {
data: string;
constructor(
private cd: ChangeDetectorRef,
private zone: NgZone,
private dataService: DataService
) {
this.getData();
}
getData(): void {
this.dataService.fetchData().subscribe(res => {
this.zone.run(() => {
this.data = res;
this.cd.markForCheck();
});
});
}
}In this example, we’re fetching data from a service and updating a variable in the component. By using it, this.zone.run()we ensure that the code runs inside Angular's zone, and Angular is aware of the changes. We then call this.cd.markForCheck() to tell Angular that it needs to re-check this component and its child components during the next change detection cycle. This combination will help keep the UI up to date without causing any issues with the view changing after it has been checked.









