This post is a the first part of “Angular Change Detection” series. Here I give a general overview of change detection and explain how NgZone works.

🚀 As a frontend framework, Angular strives for the best possible performance.

This means that it needs to re-render the view only when needed — when the bindings change. This is exactly why the concept of Change Detection was created.

The knowledge of how the Change Detection mechanism works will let you write more efficient and performant Angular code. So jump in 😉

How does Angular Detect the changes?

Each time when the component instance is created — Angular framework creates an associated View object. In simple words, in the change detection mechanism “View” stands for “Component Instance”.

Every View contains the list of its bindings. Let’s say we have the following Angular component:

component.html
component.ts
Simple result

This will enforce Angular to create a View with the following bindings: ::greeting, ::author.firstName, ::author.lastName, ::timestamp.

Now, when any of these bindings are changed — Angular will run the change detection cycle to reflect the changes on the view.

For example, when we click the Update button — we can see that the timestamp value changes on the view. However, notice that until the button is clicked — the change detection mechanism is NOT triggered at all.

But how does Angular know that the value is indeed changed? This is done by just the JavaScript “strict equals” operator `===` with minor adjustments. If any of the bingings’ value does not match its previous value (change detected)— the view is re-rendered and all the bindings are re-calculated.

The role of NgZone

Despite the common misconception, Angular’s change detection mechanism does not depend on NgZone and can nicely work without it being used at all.

We will take a closer look at its real role. Let’s modify our component a bit:

component.ts

What’s changed here:

  1. We change the author’s name in a second delay after the component was initialized.
  2. We create a counter that checks how many times the component’s View was checked and log the value to the console.

So what is the result?

We see that the name is indeed changed but there are 3 view checks in place. So what is happening here?

  1. The first check is done when the component is ready to be rendered (right after the ngAfterViewInit hook). It is needed for Angular to know the initial values of component’s bindings.
  2. The second check is done afterwards to make sure that the values have not been changed after the previous check (this check is done only in the dev mode).
  3. The third check appears with the delay and is triggered by the change in ‘author.firstName’ value. Here ngZone takes the stage! It creates a dedicated “zone” for the Angular app and notifies about any asynchronous changes. It can be setTineout/setInterval call like in our case or any other operations that are done in the asynchronous manner: user input, click, eventListener or XMLHTTP request.

Note that NgZone triggers the change detection even in the cases when no changes should be reflected on the UI. For example, if we make an HTTP call to load something asynchronously but the data response data is bound to the View — Angular will anyway run the additional change detection checks.

Let’s say we update our timed-out logic not to change the UI-bound “author.firstName” but simply log the hardcoded string to the console.

We will still see that 3 checks were fired despite nothing on UI can be changed!

How to avoid false-positive NgZone triggers

The rule of a thumb is to run all of your non-UI-bound asynchronous logic outside of NgZone. Angular provides the NgZone injectable for this purpose. Let’s use it and see the result:

Extracting the asynchronous context outside of NgZone

Now we see that there extra trigger disappears:


👋🏻 Thank you for reading. This was the general overview of Change Detection mechanism in Angula

👀 In the next post we will look into ChangeDetectionStrategy deeply and see when and how to use it to achieve the best possible performance of our Angular components.

💬 Any your thoughts and ideas are very appreciated in the comments below.

Additional Reading

https://blog.angular-university.io/how-does-angular-2-change-detection-really-work

https://indepth.dev/posts/1137/these-5-articles-will-make-you-an-angular-change-detection-expert

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *