Быстрое обновление изображения с URI данных приводит к кэшированию и утечке памяти.

У меня есть веб-страница, которая быстро передает JSON с сервера и отображает его биты, примерно 10 раз в секунду. Одна часть представляет собой изображение PNG в кодировке base64-. Я нашел несколько разных способов отображения изображения, но все они вызывают неограниченное использование памяти. Он увеличивается с 50 МБ до 2 ГБ в течение нескольких минут. Случается с Chrome, Safari и Firefox. IE не пробовал.

Сначала я обнаружил использование памяти, взглянув на Activity Monitor.app --Процесс Google Chrome Renderer постоянно потребляет память. Затем я посмотрел на инспектор ресурсов Chrome(View> Developer> Developer Tools,Resources)и увидел, что он кэширует изображения . Каждый раз, когда я менял img srcили создавал новое изображение()и устанавливал его 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 МБ и останавливается), но он медленный,особенно в Safari (~50% загрузки ЦП там, 17% в Chrome). Идея возникла из этого похожего вопроса SO:Утечка URI данных в Safari (была:Утечка памяти с холстом 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);

25
задан Community 23 May 2017 в 12:02
поделиться