Advanced Change Detection
Change detection in Angular ensures that the views are updated with the latest data. This guide covers advanced topics in change detection, including OnPush strategy, manual triggering, and performance optimizations.
OnPush Change Detection Strategy
The OnPush change detection strategy improves performance by only checking components with changed inputs:
// some.component.ts
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
@Component({
selector: 'app-some',
templateUrl: './some.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SomeComponent {
@Input() data: any;
}
Manual Change Detection
Sometimes, you need to manually trigger change detection. Use the ChangeDetectorRef
for this purpose:
// some.component.ts
import { ChangeDetectorRef, Component } from '@angular/core';
@Component({
selector: 'app-some',
template: `{{ data }}`
})
export class SomeComponent {
data: any;
constructor(private cdr: ChangeDetectorRef) {}
updateData(newData: any) {
this.data = newData;
this.cdr.detectChanges(); // Manually trigger change detection
}
}
Using Async Pipe
The Async pipe automatically subscribes to observables and marks the component for change detection when new data arrives:
// some.component.ts
import { Component } from '@angular/core';
import { Observable, of } from 'rxjs';
@Component({
selector: 'app-some',
template: `{{ data$ | async }}`
})
export class SomeComponent {
data$: Observable = of('Hello World');
}
Immutable Data Structures
Using immutable data structures helps Angular efficiently detect changes:
// some.component.ts
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
@Component({
selector: 'app-some',
templateUrl: './some.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SomeComponent {
private _data: any;
@Input()
set data(value: any) {
this._data = { ...value }; // Creating a new object reference
}
get data() {
return this._data;
}
}
TrackBy Function
The TrackBy function improves the performance of *ngFor
by tracking items by a unique identifier:
// some.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-some',
template: `
{{ item.name }}
`
})
export class SomeComponent {
items = [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }];
trackById(index: number, item: any): number {
return item.id;
}
}
Optimizing Template Expressions
Avoid complex logic in template expressions. Move complex logic to component methods or properties:
// bad.component.html
{{ someComplexFunction() }}
// good.component.ts
get computedValue() {
return this.someComplexFunction();
}
Zone.js Optimizations
Reduce the impact of Zone.js on performance by using NgZone
to run code outside Angular's zone:
// some.component.ts
import { Component, NgZone } from '@angular/core';
@Component({
selector: 'app-some',
template: `{{ data }}`
})
export class SomeComponent {
data: any;
constructor(private ngZone: NgZone) {}
updateData(newData: any) {
this.ngZone.runOutsideAngular(() => {
// Code that does not need Angular's change detection
this.data = newData;
});
}
}
Key Points
- The OnPush change detection strategy improves performance by only checking components with changed inputs.
- Use the
ChangeDetectorRef
to manually trigger change detection when needed. - The Async pipe automatically subscribes to observables and marks the component for change detection when new data arrives.
- Using immutable data structures helps Angular efficiently detect changes.
- The TrackBy function improves the performance of
*ngFor
by tracking items by a unique identifier. - Avoid complex logic in template expressions by moving it to component methods or properties.
- Reduce the impact of Zone.js on performance by using
NgZone
to run code outside Angular's zone.
Conclusion
Advanced change detection techniques in Angular help optimize the performance of your applications. By using the OnPush strategy, manually triggering change detection, utilizing the Async pipe, and other performance optimizations, you can ensure your Angular applications run efficiently. Happy coding!