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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM