Change Detection
Written By: Avinash Malhotra
Updated on
Change Detection is one of the important Strategy in Angular and Angular does is very well using zone.js. Change Detection is responsible for how our data in model (component) is synchronized with view layer (template). Any change in value through click or user input is instantly change in component.
Change Detection also update DOM when a value is changed in component.
Types of Change Detections
Default (zone.js) | zone.js is default change Detection |
---|---|
onPush | when @Input parameter change |
default (zone.js)
Default Strategy in Angular use zone.js library or ngZone . This asynchronously check every time a change has done.
Angular change detector comes in action due to following reasons.
Reason of change detections
- Events like click, change etc
- Ajax or Fetch
- JS Timers, setInterval or setTimeout
Click based change
When Click event is triggered by user on h1 element, the value of title will change in model and update in view .
<!--app.component.html-->
<h1 (click)="changeTitle()">{{title}}</h1>
<!--app.component.ts-->
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
imports: [ ],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'myApp';
changeTitle(){
this.title="Hello Angular";
}
}
timer based change
After 1 second, the title value will change in model and update in DOm view.
<!--app.component.html-->
<h1>{{title}}</h1>
<!--app.component.ts-->
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
imports: [ ],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'myApp';
ngOnInit(){
setTimeout(()=>{
this.title="hello";
},1000);
}
}
Drawbacks of default change Strategy
Although Default Strategy in Angular is good for all change detections, but lets first understand its consequences.
The major consequence is rechecking again and again. When a change is detected in child component, Angular will perform change detection form root component to all children.
Each component has its own change detector. The change detector run from top to bottom in the tree.
Imagine an event occurred on component cc-12, which will change value of property. Change detector will work from top to bottom and on all components, including component 2 and its children.
We might think that this can cause performance issue, but actually its not 100% true. But to limit number of checks and to avoid zone pollution, we can us onPush Strategy.
onPush Strategy
onPush Strategy force Angular to run change detection on component and sub tree only. This is done by setting changeDetection:ChangeDetectionStrategy.OnPush in component decorator.
onPush will work only when the reference of @Input property is changed. This will only check the tree. This can improve performance of angular application when changes are frequent.
When did onPush works
- @Input reference changes
- Event Listener
- timers
- Ajax/fetch
<!--app.component.html-->
<h1>{{title}}</h1>
<button (click)="changeTitle()">Click</button>
<app-home [id]="counter"></app-home>
<!--app.component.ts-->
import { ChangeDetectionStrategy, Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
imports: [ ],
changeDetection:ChangeDetectionStrategy.OnPush,
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'myApp';
counter=10;
changeTitle(){
this.counter=this.counter+1;
}
}
<!--home.component.html-->
<p>home works!</p>
<p>{{y}}</p>
<!--home.component.ts-->
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-home',
standalone: true,
imports: [],
templateUrl: './home.component.html',
styleUrl: './home.component.css'
})
export class HomeComponent {
@Input() y=0;
}