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)});
  }
}
相關文章
相關標籤/搜索