![](/img/trans.png)
[英]Horrible Canvas GetImageData() / PutImageData() performance on mobile
[英]Performance issue with canvas.getImageData + canvas.putImageData
我經常調用 getImageData/putImageData,它導致我的 Chrome 進程填滿,直到它達到 2.5Gb 內存時崩潰。
我正在使用帶有傳單熱圖插件的simpleheat.js在畫布上顯示熱圖。
基本上,我經常調用 draw fn 來建立“隨時間變化的熱圖”效果。 我處理每次運行(每個 getImageData/putImageData)的數據是 4Mb,同時以 10-20 fps 調用。
我想知道如何優化這段代碼。 我對使用畫布知之甚少。
這是來自simpleheat.js
的相關代碼:
draw: function() {
...
var colored = ctx.getImageData(0, 0, this._width, this._height);
this._colorize(colored.data, this._grad);
ctx.putImageData(colored, 0, 0);
},
_colorize: function (pixels, gradient) {
for (var i = 0, len = pixels.length, j; i < len; i += 4) {
j = pixels[i + 3] * 4; // get gradient color from opacity value
if (j) {
pixels[i] = gradient[j];
pixels[i + 1] = gradient[j + 1];
pixels[i + 2] = gradient[j + 2];
}
}
}
我試過減少 DOM 訪問(在另一個問題中建議)
var colored = ctx.getImageData(0, 0, this._width, this._height);
var coloredData = colored.data;
this._colorize(coloredData, this._grad);
colored.data = coloredData;
ctx.putImageData(colored, 0, 0);
我認為問題是瀏覽器沒有正確釋放 4Mb 的數據,因為如果我將頁面保留一段時間,內存最終會下降
我嘗試了一些愚蠢的嘗試來幫助 GC 釋放數據數組( colored.data = null
或undefined
)
創建 ctx 時,您可以給它一個屬性,使這些操作更快。
const ctx = canvas.getContext("2d", { willReadFrequently: true });
更多關於 willReadFrequently 的信息: HTML willReadFrequently 規范
此外,如果可能,請避免每幀運行 getImageData。 如果有一種方法可以在不獲取每個像素值的情況下獲取漸變的不透明度值,則可以擁有一個可以更改和放置每一幀的圖像。
您也可以完全忘記此方法並使用 gpu.js 執行相同的操作,從實現的角度來看這不會太困難。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.