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

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

原因

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

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

解决方法

在 ngZone 之外创建 echarts 实例,代码示例:

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)}); } }

 

posted on 2019-10-16 11:13  等待未知  阅读(1649)  评论(0编辑  收藏  举报

导航