最近使用websocket加ECharts做了一個實時監控的功能,發現了一個比較嚴重的問題,就是瀏覽器運行一段時間就會非常卡,之前在ECharts官網運行官方實例“動態數據 + 時間坐標軸”時,也遇到了同樣的情況,只是當時沒有當回事,現在來看原來是內存泄漏的問題。那么是什么原因導致的內存泄漏呢?
通過上次使用ECharts的經驗以及上網查資料得知,原來ECharts在每次setOption后都需要清理變量,在ECharts中是有API手動清理變量的,分別是clear()和dispose(),區別是前者只需插入參數,ECharts就會重繪圖表;而后者則是直接將ECharts對象進行清理,需要重新構建ECharts對象。另外,針對IE,也有專門的回收內存函數CollectGarbage,每次瀏覽器最小化的時候,瀏覽器都會調用該函數,清理內存。
經過親身試驗,綜合各種解決方案,挑選了一種個人認為比較好的可行方案,關鍵部分源碼如下:
setInterval()或者websocket.onmessage function(){ data0.shift(); data0.push(data0); data1.shift(); data1.push(data1); xdata.shift(); xdata.push(axisData); chart.clear();//清空ECharts chart.setOption(Option); } //IE內存回收機制 if (window.CollectGarbage) { setInterval(function () { CollectGarbage(); }, 30000); }
還有一種方案就是chart.dispose()配合echarts.init(),然后再setOption(),也是可行的,與clear()方法的不同之處在於,dispose()方法是銷毀ECharts實例,然后再重新初始化,個人覺得clear()方法好一點。
以上方法有點問題,內存泄漏的問題確實沒有了,但是用戶的操作(比如縮放或者點擊圖例等)在每次執行setInterval()或者websocket.onmessage方法時,ECharts圖表都會重置為初始化時的狀態,通過查詢官方API,找到了解決此問題的方法,代碼如下:
setInterval()或者websocket.onmessage function(){ xxdata = option.xAxis[0].data; data0 = option.series[0].data; data1 = option.series[1].data; data0.shift(); data0.push(newdata0); data1.shift(); data1.push(newdata1); xdata.shift(); xdata.push(newaxisData); userOption = ismpflow.getOption();//返回包含用戶操作的option userOption.xAxis[0].data = xxdata; userOption.series[0].data = data0; userOption.series[1].data = data1; chart.clear();//清空ECharts chart.setOption(userOption ); } //IE內存回收機制 if (window.CollectGarbage) { setInterval(function () { CollectGarbage(); }, 30000); }
有更好的解決方案歡迎交流!
本文為作者原創,轉載請注明出處。
前端交流群,群文件提供大量文檔、書籍和資料。期待你的加入!群號:127768464