Das schnelle Aktualisieren des Images mit dem Daten-URI führt zu Caching und Speicherlecks

Ich habe eine Webseite, mit schnell-streams JSON vom server und zeigt die bits, über 10-mal/Sekunde. Ein Teil ist base64-kodierte PNG-Bild. Ich habe ein paar verschiedene Möglichkeiten, um das Bild anzuzeigen, aber alle von Ihnen führen unbounded memory usage. Er steigt von 50 MB auf 2 GB innerhalb von Minuten. Passiert mit Chrome, Safari und Firefox. Habe nicht versucht, DH.

Entdeckte ich die Speicherauslastung zunächst durch einen Blick in die Aktivitätsanzeige.app -- Google Chrome Renderer-Prozess kontinuierlich frisst Speicher. Dann sah ich auf Chrome Ressource-Inspektor (View > Developer > Developer ToolsResources), und ich sah, dass es Zwischenspeichern der Bilder. Jedes mal, wenn ich änderte die img src oder erstellt ein neues Image (), und legen Sie seine srcChrome-Cache. Ich kann mir nur vorstellen, dass die anderen Browser tun das gleiche.

Gibt es eine Möglichkeit, dies zu kontrollieren Zwischenspeichern? Kann ich Sie ausschalten, oder etwas tun, hinterhältige, damit es nie passiert?

Edit: ich möchte in der Lage sein, um die Technik zu nutzen, die in Safari/Safari (Mobil). Auch, ich bin offen für andere Methoden, die schnell eine erfrischende Bild, wenn jemand eine Idee hat.

Hier sind die Methoden, die ich ausprobiert habe. Jeder befindet sich in einer Funktion, die aufgerufen wird, die auf AJAX-Abschluss.

Methode 1 - Direkt auf das src - Attribut auf eine img tag

Schnell. Zeigt sich sehr schön. Lecks wie verrückt.

$('#placeholder_img').attr('src', 'data:image/png;base64,' + imgString);

Methode 2 - Ersetzen img mit einem canvasund verwenden Sie drawImage

Zeigt feine, aber immer noch leckt.

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;

Methode 3 - in binary Konvertieren und ersetzen canvas Inhalt

Mache ich etwas falsch hier-die Bilder zeigen klein und sehen aus wie Rauschen. Diese Methode verwendet eine kontrollierte Menge an Speicher (wächst auf 100 MB und Stoppt), aber es ist langsam, vor allem in Safari (~50% CPU-Auslastung gibt es, 17% Chrom). Die Idee kam aus dieser ähnlichen Frage ALSO: Daten URI Leck in Safari (war: Speicherverlust mit HTML5 canvas)

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

InformationsquelleAutor der Frage Dave | 2012-03-28

Schreibe einen Kommentar