diff --git a/aio/content/guide/change-detection-zone-pollution.md b/aio/content/guide/change-detection-zone-pollution.md new file mode 100644 index 00000000000..a73f8e80ad9 --- /dev/null +++ b/aio/content/guide/change-detection-zone-pollution.md @@ -0,0 +1,60 @@ +# Resolving Zone Pollution + +**Zone.js** is a signaling mechanism that Angular uses to detect when an application state might have changed. It captures asynchronous operations like `setTimeout`, network requests, and event listeners. Angular schedules change detection based on signals from Zone.js + +There are cases in which scheduled [tasks](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide#tasks) or [microtasks](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide#microtasks) don’t make any changes in the data model, which makes running change detection unnecessary. Common examples are: +* `requestAnimationFrame`, `setTimeout` or `setInterval` +* Task or microtask scheduling by third-party libraries + +This section covers how to identify such conditions, and how to run code outside the Angular zone to avoid unnecessary change detection calls. + +## Identifying unnecessary change detection calls + +You can detect unnecessary change detection calls using Angular DevTools. Often they appear as consecutive bars in the profiler’s timeline with source `setTimeout`, `setInterval`, `requestAnimationFrame`, or an event handler. When you have limited calls within your application of these APIs, the change detection innovation is usually caused by a third-party library. + + + +In the image above, there is a series of change detection calls triggered by event handlers associated with an element. That’s a common challenge when using third-party, non-native Angular components, which do not alter the default behavior of `NgZone`. + + +## Run tasks outside NgZone + +In such cases, we can instruct Angular to avoid calling change detection for tasks scheduled by a given piece of code using [NgZone](https://angular.io/guide/zone). + +```ts +import { Component, NgZone, OnInit } from '@angular/core'; +@Component(...) +class AppComponent implements OnInit { + constructor(private ngZone: NgZone) {} + ngOnInit() { + this.ngZone.runOutsideAngular(() => setInterval(pollForUpdates), 500); + } +} +``` + +The snippet above instructs Angular that it should execute the `setInterval` call outside the Angular Zone and skip running change detection after `pollForUpdates` runs. + +Third-party libraries commonly trigger unnecessary change detection cycles because they weren't authored with Zone.js in mind. Avoid these extra cycles by calling library APIs outside the Angular zone: + +```ts +import { Component, NgZone, OnInit } from '@angular/core'; +import * as Plotly from 'plotly.js-dist-min'; + +@Component(...) +class AppComponent implements OnInit { + constructor(private ngZone: NgZone) {} + ngOnInit() { + this.zone.runOutsideAngular(() => { + Plotly.newPlot('chart', data); + }); + } +} +``` + +Running `Plotly.newPlot('chart', data);` within `runOutsideAngular` instructs the framework that it shouldn’t execute change detection after the execution of tasks scheduled by the initialization logic. + +For example, if `Plotly.newPlot('chart', data)` adds event listeners to a DOM element, Angular will not execute change detection after the execution of their handlers. + +@reviewed 2022-05-04 diff --git a/aio/content/images/guide/change-detection/zone-pollution.png b/aio/content/images/guide/change-detection/zone-pollution.png new file mode 100644 index 00000000000..f4e825d3856 Binary files /dev/null and b/aio/content/images/guide/change-detection/zone-pollution.png differ