Using Angular Change Detection Effectively

Jagjeet Singh
5 min readSep 17, 2021
angular change detection

Overview

Change Detection is the mechanism angular uses to keep DOM in synchronization with component data by re-rendering the DOM whenever the data is changed.

Every component in angular has an associated View, This View contains the reference of component instance and has its own change detector which is nothing but just a method responsible for detecting changes and updating DOM for that View.

change detection tree

A View is re-rendered only if it is marked as Dirty which means the View has changed and needs to be updated.

There are two different change detection strategies, Default and OnPush . Based on the strategy used, angular decides when change detection should be triggered.

export enum ChangeDetectionStrategy { 
OnPush = 0,
Default = 1
}

Default Change Detection Strategy

As the name implies, Every component has Default strategy set on it by default. In this strategy, angular triggers the change detection whenever any of the following events are fired :

  • Browser events like click, mouseover, etc.
  • Timers like setTimeout() or setInterval()
  • AJAX calls

When user clicks on a button, Change detection is triggered for every View in the change detection tree starting from the root and the value of every template expression in the component template is checked, if any of the value is changed, the View associated with that component is marked as Dirty and re-rendered.

Default change detection strategy

Suppose, we have an AppComponent defined as:

When Change Name Button is clicked, change detection is triggered and value of firstname property of user will be updated and since we are using it in the component template, the View is marked as Dirty and DOM is updated.

Traversing all the components in the tree and running change detection is a heavy process and degrades the performance of the application, to overcome this, Angular allows us to control when and on which components change detection should run by usingOnPush strategy.

OnPush Change Detection Strategy

When OnPush strategy is used on a compoent, Change detection is triggered only when the reference of any Input Property is changed or any DOM event is fired from that component or any of its children.

Unlike Default change detection strategy, Timers or HTTP calls do not trigger change detection.

OnPush change detection strategy

Suppose we have a ChildComponent with ChangeDetectionStrategy set to OnPush, This component is used inside the AppComponent and user is passed as an Input property.

Now when ChangeName method runs on button click in AppComponent, Change detection will not be triggered for ChildComponent as the reference of user object is same.

ChangeDetectorRef

ChangeDetectorRef is the base class that provides many methods which we can use to manipulate the default change detection behavior by injecting it into our components.

export abstract class ChangeDetectorRef {
abstract markForCheck(): void;
abstract detach(): void;
abstract detectChanges(): void;
abstract checkNoChanges(): void;
abstract reattach(): void;
}

markForCheck()

markForCheck() method is used in combination with OnPush change detection strategy to manually mark the current view and all of its successors as to be Checked Once so that they can be checked again during the current or next change detection cycle.

markForCheck() method

Using markForCheck() with ngDoCheck Lifecycle hook: Angular runs the ngDoCheck lifecycle method of the immediate child component whenever change detection runs for the parent component irrespective of the change detection strategy. We can use this behavior to improve the performance of the App by calling the markForCheck() method in ngDoCheck() by checking if firstname property has changed.

change detection will not run by default when firstname is changed As the change detection strategy is OnPush for ChildComponent, but ngDoCheck life cycle method will run whenever change detection is triggered for the app component, in this method we can check if firstname property of user object is changed and then call the markForCheck() accordingly, which will mark the current View as to be Checked Once.

detach()

detach() method of ChangeDetectorRef class can be used to detach the current view and all of its children from the change detection tree, detached views are not checked by angular during change detection even if they are marked Dirty using markForCheck().

detach() method

One way to run change detection when view is detached is by using detectChanges() method.

detectChanges()

This method can be used in combination with detach() to manullay trigger Change detection for the current View and its children irrespective of the state and change detection strategy of the component.

detectChanges() method

Improving performance by limiting the number of checks: Suppose we have data that changes very frequently, and we don’t necessarily need to update the view for every change. In this case, we can use detach() along with detectChanges() to improve the performance by limiting the number of checks.

In the ChildComponent, suppose we have another property profileViews in user object that changes frequently, To limit the number of checks, we can detach the view using detach() method and call detectChanges() every few seconds to update the view.

reattach()

This method is used to activate the change detection for the current view by re-attaching the previously detached view to the change detection tree.

--

--

Jagjeet Singh

Frontend Engineer, Angular | React | JavaScript | Web Development