mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
a6b99254e1
Relative links have 2 advantages : * They're not marked as external links * When on a specific doc version, the link point to the same version. PR Close #50080
61 lines
3.2 KiB
Markdown
61 lines
3.2 KiB
Markdown
# 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.
|
||
|
||
In some cases 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 invocation is usually caused by a third-party library.
|
||
|
||
<div class="lightbox">
|
||
<img alt="Angular DevTools profiler preview showing Zone pollution" src="generated/images/guide/change-detection/zone-pollution.png">
|
||
</div>
|
||
|
||
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, you can instruct Angular to avoid calling change detection for tasks scheduled by a given piece of code using [NgZone](/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 preceding snippet instructs Angular to call `setInterval` 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.ngZone.runOutsideAngular(() => {
|
||
Plotly.newPlot('chart', data);
|
||
});
|
||
}
|
||
}
|
||
```
|
||
|
||
Running `Plotly.newPlot('chart', data);` within `runOutsideAngular` instructs the framework that it shouldn’t run 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 does not run change detection after the execution of their handlers.
|
||
|
||
@reviewed 2022-05-04
|