How Angular change detection works?

Darshan Trambadiya

May 22, 2020

5 min readLast Updated Sep 24, 2020

How Angular change detection works

What is change detection?

  • The basic mechanism of the change detection is to perform checks against two states, one is the current state, the other is the new state. If one of this state is different of the other, then something has changed, meaning we need to update (or re-render) the view.
Change Detection means updating the view (DOM) when the data has changed.

Change Detection is done in two steps

  • Angular’s change detection is done in two steps, the first one is done by having the developer updating the application model. He can do it by changing the property of a component or emitting an event. Then Angular’s job will be to reflect the state of the model in the view, by re-rendering it. Usually this means that Angular will update by sending an event and/or by property bindings.
  1. Update the application model (developer);
  2. Reflect the state of the model in the view (Angular).

How it works?

  • Angular performs change detection on all components (from top to bottom) every time something changes in your app from something like a user event or data received from a network request. Change detection is very performant, but as an app gets more complex and the amount of components grows, change detection will have to perform more and more work. Let's take an example
Todo application’s component tree
  • In Angular, each application is a bunch of components glued together with some Inputs and Outputs to be able to propagate data and model states.
  • As image show, we have a fairly simple application that has a TodosComponent managing a list of TodoComponent. If we modify this list, by changing the value of the first item of the todos’ list (in yellow), we will have the following flow:
  1. The developer is making changes to the model (like a component’s bindings);
  2. Angular’s change detection kicks in to propagate the changes;
  3. Change detection goes through every components in the component tree (from top to bottom) to check if the model it depends on changed;
  4. If Yes, it will update the component;
  5. Angular updates the component’s view (DOM).
The way Angular runs the change detection by starting from the top and continuing until it reaches the bottom, makes the system more predictable and more performant.

Angular Change Detection Strategies

Angular provides you two Change Detection Strategies, the default one and the onPush.

ChangeDetectionStrategy.Default

  • In order to know whether the view should be updated, Angular needs to access the new value, compare it with the old one, and make the decision on whether the view should be updated.
  • By default, Angular makes no assumption on what the component depends upon. So it has to be conservative and will checks every time something may have changed, this is called dirty checking. In a more concrete way, it will perform checks for each browser events, timers, XHRs and promises.
  • This can be problematic when you’re starting to have a big application with many components, specially if you’re focused on performance.
By default, Angular has to be conservative and will checks every time something may have changed, this is called dirty checking.

Example :

Consider parent component as TodosComponent like

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

@Component({
 selector: 'app-todos',
 template: `
  <div>
   <input #word type="text" />
   <button (click)="addWord(word.value)">Add Word</button>
   <app-todo [data]="words"></app-todo>
  </div>
 `,
})
export class TodosComponent {
 words = ['Car', 'Bike'];

 addWord(word) {
  this.words.push(word);
 }
}
todos.component.ts

Consider child component as TodoComponent like

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

@Component({
 selector: 'app-todo',
 template: `
  <p>TodoComponent</p>
  <ul>
   <li *ngFor="let item of data">{{ item }}</li>
  </ul>
 `,
 changeDetection: ChangeDetectionStrategy.Default,
})
export class TodoComponent {
 @Input() data: Array<string> = [];
}
todo.component.ts
  • In above example, As we applied ChangeDetectionStrategy.Default, Therefore Child(TodoComponent) is automatic update(re-render the view) when we click on parent's "Add Word" button.

ChangeDetectionStrategy.onPush

  • When using the onPush strategy on the component, you basically say to Angular that it should not make any guess on when it needs to perform the check for change. It will rely only on the change of the Input references, some events triggered by itself (the component) or one of its children. Lastly, you, the developer, can ask explicitly Angular to do it with the componentRef.markForCheck() method.
  • With onPush, the component only depends on its inputs and embraces the immutability, the change detection strategy will kicks in when:
  1. The Input reference changes;
  2. An event originated from the component or one of its children;
  3. Run change detection explicitly (componentRef.markForCheck());
  4. Use the async pipe in the view.
With onPush, Angular will only depend on the component’s inputs, events, markForCheck method, or the use of the async pipe in the template, to perform a change detection mechanism and update the view.
  • This has for effect to gain a lot on performance, Angular doesn’t do any guess or useless work. It makes your application embrace the immutability, via its components.

Example :

Consider same parent component as TodosComponent like

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

@Component({
 selector: 'app-todos',
 template: `
  <div>
   <input #word type="text" />
   <button (click)="addWord(word.value)">Add Word</button>
   <app-todo [data]="words"></app-todo>
  </div>
 `,
})
export class TodosComponent {
 words = ['Car', 'Bike'];

 addWord(word) {
  this.words.push(word);
 }
}
todos.component.ts

Consider child component as TodoComponent like

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

@Component({
 selector: 'app-todo',
 template: `
  <p>TodoComponent</p>
  <button (click)="updateView()">Trigger Change Detection</button>
  <ul>
   <li *ngFor="let item of data">{{ item }}</li>
  </ul>
 `,
 changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TodoComponent {
 @Input() data: Array<string> = [];

 constructor(private ref: ChangeDetectorRef) {}

 updateView() {
  /**
   * View will not update even @Input() data change as we appied       	  	 * ChangeDetectionStrategy.OnPush. To update view, we must run change 	 * detection manuallly by clicking on "Trigger Change Detection"
   * button
   */
  this.ref.markForCheck();
 }
}
todo.component.ts
  • In above example, As we applied ChangeDetectionStrategy.OnPush, Therefore Child(TodoComponent) is not automatic update(re-render the view) when we click on parent's "Add Word" button. To update the child view, we need to manually trigger change detection whenever we need so that we can get better performance.

Summary

  • To automatic change detection, Angular use by default ChangeDetectionStrategy.Default strategy but it cause performance issue when our application become larger.
  • So for larger application, It would be better to use ChangeDetectionStrategy.OnPush strategy as it saves performance.

Third Rock Techkno is a leading IT services company. We are a top-ranked web, voice and mobile app development company with over 10 years of experience. Client success forms the core of our value system.

We have expertise in the latest technologies including angular, react native, iOs, Android and more. Third Rock Techkno has developed smart, scalable and innovative solutions for clients across a host of industries.

Our team of dedicated developers combine their knowledge and skills to develop and deliver web and mobile apps that boost business and increase output for our clients.

Projects Completed till now.

Discover how we can help your business grow.

"Third Rock Techkno's work integrates complex frameworks and features to offer everything researchers need. They are open-minded and worked smoothly with the academic subject matter."

- Dr Daniel T. Michaels, NINS

Related Resources

Our Services

You May Also Like