Angular 中使用 echarts 致使 CPU 占用率太高的问题

参考: https://github.com/xieziyu/ngx-echarts/issues/15javascript

缘由

为了让视图和模型同步,Angular 会在浏览器的异步接口(例如 setTimeout ) 的回调函数执行结束后进行变动检测。由于浏览器中js脚本的运行是事件驱动的,一段JS代码的执行必定是某个异步接口触发的,因此在异步接口调用结束后进行变动检测, Angular 就不会错过用户代码对数据的修改。为了可以感知到一个异步接口被调用了,Angular 使用了 Zone.js, 全部用户的代码默认都在 Zone 中运行,并且在 NgZone 中,一切异步的 Web API 都已经被 patch 过了,这样就能够实如今一个异步接口的回调函数的执行前/执行后插入指定的代码。java

一个 echarts 实例,彷佛会周期性调用 window.requestAnimationFrame() , 若是页面上有不少 echarts 实例,就会致使大量的 window.requestAnimationFrame() 调用, 而调用这样一个异步接口,又会触发Angular 的变动检测,大量的变动检测会消耗大量的 CPU, 从任务管理器中能够看出某个Chrome 进程的 CPU 开销异常大,可能达到  100%。 在 Chrome Dev tool 中进行 Performance 分析,能够看到大量的 Animation Frame Fired 事件,以下图所示:git

解决方法

在 ngZone 以外建立 echarts 实例,代码示例:github

import { NgZone } from '@angular/core';

...
export class MyComponent {  ...  mychart;
  constructor(private ngZone: NgZone) {}

  createEchart() {
    return this.ngZone.runOutsideAngular(() => {this.mychart = echarts.init(this.el.nativeElement)});
  }
}
相关文章
相关标签/搜索