サーバーから JSON を高速でストリーミングし、その一部を毎秒約 10 回表示する Web ページがあります。1 つの部分は、base64 でエンコードされた PNG 画像です。画像を表示するいくつかの異なる方法を見つけましたが、それらはすべて無制限のメモリ使用量を引き起こします。数分で 50MB から 2GB に増加します。Chrome、Safari、および Firefox で発生します。IEは試していません。
Activity Monitor.app を見て、最初にメモリ使用量を発見しました。Google Chrome レンダラー プロセスは継続的にメモリを消費します。次に、Chrome のリソース インスペクター ( View
> Developer
> Developer Tools
、Resources
) を見たところ、画像をキャッシュしていることがわかりました。img src
を変更するか、新しい Image() を作成してその を設定するたびにsrc
、Chrome はそれをキャッシュしました。他のブラウザも同じことをしているとしか思えません。
このキャッシュを制御する方法はありますか? オフにすることはできますか?
編集: Safari/Mobile Safari でこの手法を使用できるようにしたいと思います。また、アイデアがあれば、画像をすばやく更新する他の方法も受け入れます。
ここに私が試した方法があります。それぞれが、AJAX の完了時に呼び出される関数に存在します。
方法 1 -タグにsrc
属性を直接設定するimg
速い。きれいに表示します。狂ったように漏れます。
$('#placeholder_img').attr('src', 'data:image/png;base64,' + imgString);
方法 2 - に置き換えimg
てcanvas
使用するdrawImage
正常に表示されますが、まだ漏れます。
var canvas = document.getElementById("placeholder_canvas");
var ctx = canvas.getContext("2d");
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
}
img.src = "data:image/png;base64," + imgString;
方法 3 - バイナリに変換してcanvas
内容を置き換える
ここで何か間違ったことをしています。画像が小さく表示され、ランダム ノイズのように見えます。この方法では、制御された量のメモリが使用されます (100 MB に増加すると停止します) が、特に Safari では低速です (CPU 使用率は 50% まで、Chrome では 17%)。アイデアは、この同様の SO の質問から生まれました: Safari でのデータ URI リーク (以前は: HTML5 キャンバスでのメモリ リーク)
var img = atob(imgString);
var binimg = [];
for(var i = 0; i < img.length; i++) {
binimg.push(img.charCodeAt(i));
}
var bytearray = new Uint8Array(binimg);
// Grab the existing image from canvas
var ctx = document.getElementById("placeholder_canvas").getContext("2d");
var width = ctx.canvas.width,
height = ctx.canvas.height;
var imgdata = ctx.getImageData(0, 0, width, height);
// Overwrite it with new data
for(var i = 8, len = imgdata.data.length; i < len; i++) {
imgdata.data[i-8] = bytearray[i];
}
// Write it back
ctx.putImageData(imgdata, 0, 0);