The automatic change detection made on UI components by asynchronous operations like http requests which are taking more time to receive the response from backend or timers(setTimeout() or setInterval()) loops etc are handled by zone.js.

NgZone is a wrapper around zone.js used to improve the performance of asynchronous tasks that don’t require UI updates. These async tasks are run outside the angular by using runOutsideAngular() and if needed those tasks will again run inside the angular by using run() to make change detections on UI.

In this article we are printing the odd numbers from 1 to 20 using the runOutsideAngular() and run() functions. On click button the interval is running outside the angular so every interval the incremented number change detections are not effect on the UI. If the incremented number is an odd number then we are using run() to update the number value on the UI.
You can refer the example here:
https://github.com/KtreeOpenSource/AngularExamples/tree/master/ngZoneDemo

Step:1

Create a new angular project by running command

ng new ngZoneDemo

This create ngZoneDemo angular project repository

Step:2

Import NgZone in App component

.src/app/app.component.ts

import { NgZone } from ‘@angular/core’;
class AppComponent {
constructor(private _ngZone: NgZone) { }
}

Step:3

Executing code outside or inside angular Zone.

run(): function used to execute the code synchronously inside the angular zone. If you created a block of statements in runOutsideAngular(), those statements will be again start listen by angular by using run().

runOutsideAngular(): function used to execute the code outside the angular zone means its code won’t trigger the change detections.

.src/app/app.component.html

<h1>{{number}}</h1>
<button (click)="onClickChangeNumber()">Change Number</button>

.src/app/app.component.ts

import { Component, NgZone } from ‘@angular/core’;
@Component({
selector: ‘app-root’,
templateUrl: ‘./app.component.html’
})
export class AppComponent {
number = 0;
constructor(private _ngZone: NgZone) { }
onClickChangeNumber() {
this._ngZone.runOutsideAngular(() => {
const interval = setInterval(() => {
if (this.number % 2 !== 0) {
if (this.number > 20) {
clearInterval(interval);
} else {
this._ngZone.run(() => {
console.log(this.number, ‘running inside angular’);
});
}
}
this.number++;
}, 500);
});
}
}