Javascript 多个图像的context.drawImage最终会导致FireFox崩溃
我正在创建一个图像上传,应该能够接受至少1000张图像。用户选择/拖放图像后,应显示图像以供预览。然后,用户将单击上载按钮启动上载 我已经实现了整个功能,它在Chrome上运行得很好。但这在Firefox中失败了 我创建了一个排队机制,在某个时间点,一旦用户选择了图像,浏览器中只会加载n个图像 超过20个映像也会发生崩溃(即使使用队列机制创建一批1个映像)。我已经使用Firefox中的Tab memory usage Plugin()检查了内存使用情况。它甚至会因40 MB的内存利用率而崩溃。所以我想,这不是因为内存泄漏Javascript 多个图像的context.drawImage最终会导致FireFox崩溃,javascript,jquery,html,firefox,canvas,Javascript,Jquery,Html,Firefox,Canvas,我正在创建一个图像上传,应该能够接受至少1000张图像。用户选择/拖放图像后,应显示图像以供预览。然后,用户将单击上载按钮启动上载 我已经实现了整个功能,它在Chrome上运行得很好。但这在Firefox中失败了 我创建了一个排队机制,在某个时间点,一旦用户选择了图像,浏览器中只会加载n个图像 超过20个映像也会发生崩溃(即使使用队列机制创建一批1个映像)。我已经使用Firefox中的Tab memory usage Plugin()检查了内存使用情况。它甚至会因40 MB的内存利用率而崩溃。所
function readAndDisplay(file, index){
id = getFileId(file);
reader = new FileReader();
reader.onload = function (e) {
addImageCard(file, index);
resizeImage(e, index);
delete this;
//$('#image' + id).attr('src', e.target.result);
}
reader.readAsDataURL(file);
}
function resizeImage(fileReaderEvent, index){
var img = new Image();
img.onload=function(){
var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
var canvas = document.getElementById("image" + index);
var ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
img.src = "";
delete canvas;
delete ctx;
img = null;
delete fileReaderEvent;
uploadQueue.push(index);
if(loadImageIterator < updatedFiles.length){
loadImage(updatedFiles[loadImageIterator++]);
}
else{
updatedFiles = [];
}
}
img.src = fileReaderEvent.target.result;
var md5 = CryptoJS.MD5(fileReaderEvent.target.result).toString();
console.log(md5);
}
function addImageCard(file, index){
imageHolder = $("#imageholder");
imageCard = $("<div>", {
class: "col m1 s4",
id: "card" + index
});
innerDiv = $("<div>", {
class: "card"
});
cardImage = $("<div>", {
class: "card-image",
}).append($("<canvas>", {
id: "image" + index,
css: {
width: "100%"
}
//src: "images/sample-1.jpg"
})).append($("<span>", {
class: "card-title",
text: ""
}));
cardContent = $("<div>",{
class: "card-content",
html: "<p>" + file.name + "</p>"
});
cardAction = $("<div>", {
class: "card-action"
});
removeButton = $("<a>", {
title: "Remove",
css: {
"font-size": "20px"
},
click: function(){
remove(index)
}
}).append($("<span>", {
class: "glyphicon glyphicon-remove-circle"
}));
uploadButton = $("<a>", {
title: "Upload Now",
css: {
"font-size": "20px",
float: "right",
"margin-right": "4px"
}
}).append($("<span>", {
class: "glyphicon glyphicon-cloud-upload"
}));
cardAction.append(removeButton);
cardAction.append(uploadButton);
innerDiv.append(cardImage);
innerDiv.append(cardContent);
innerDiv.append(cardAction);
imageCard.append(innerDiv);
imageHolder.append(imageCard);
}
函数读取和显示(文件、索引){
id=getFileId(文件);
reader=newfilereader();
reader.onload=函数(e){
addImageCard(文件、索引);
调整图像大小(e,索引);
删除此项;
//$('#image'+id).attr('src',e.target.result);
}
reader.readAsDataURL(文件);
}
函数大小图像(fileReaderEvent,索引){
var img=新图像();
img.onload=函数(){
var MAX_WIDTH=800;
var最大高度=600;
变量宽度=img.width;
var高度=img高度;
如果(宽度>高度){
如果(宽度>最大宽度){
高度*=最大宽度/宽度;
宽度=最大宽度;
}
}否则{
如果(高度>最大高度){
宽度*=最大高度/高度;
高度=最大高度;
}
}
var canvas=document.getElementById(“图像”+索引);
var ctx=canvas.getContext(“2d”);
画布宽度=宽度;
canvas.height=高度;
ctx.drawImage(img,0,0,宽度,高度);
img.src=“”;
删除画布;
删除ctx;
img=null;
删除fileReaderEvent;
uploadQueue.push(索引);
if(loadImageIterator“
});
cardAction=$(“”{
类:“卡片操作”
});
removeButton=$(“
Firefox崩溃报告-您的代码中存在一些问题:
- 第一个是在
FileSelectHandler()
(onchange)中的for循环中同步调用loadImage()
,如果循环没有完成(在我的comp上,20个图像发生了15次),那么一旦绘制完成,它本身就会异步回调loadImage()
。
只要在onchange上调用它一次并允许异步回调就足够了
- 第二个在回调检查中:
if(loadImageIterator
应替换为
if(++loadImageIterator
或者第一次调用将传递更新的文件[0]
- 第三个是变量声明。您忘记了
var
之前的reader
,newFile
和其他一些变量,从而生成了这些全局变量
这是一个不会在Chrome或FF中抛出任何错误,而不会自己删除任何内容的应用程序。delete
不会做您认为它会做的事情。它只从对象中删除属性,不会删除对象引用(因此垃圾收集器不会回收对象的内存).Delete在这里几乎没有意义。我添加它只是为了确定。这里的所有变量都是本地变量。因此,它们在理想情况下会自行进行垃圾收集。如果其中一些变量由于我使用它们的方式而必然导致泄漏,请务必让我知道。如果不进行所有这些无用的清理,是否也会发生这种情况?这种情况正在发生即使我在做这些无用的清洁;)顺便说一句,如果没有这些无用的清洁,chrome会发出Aww快照。所以我被迫这么做。这似乎不是一个正确的解决方案"问题出在我身上。如果我认为这是因为您的代码导致页面无响应而发生的,那么您可以尝试一下requestAnimationFrame
throttling。我现在甚至没有时间重现错误,所以我无法判断它是否有效,但它应该给浏览器留出时间来处理每个对象和垃圾收集应该如此。嗨,Kaido,我的FF正在为你的小提琴崩溃,但Chrome工作正常。你能检查一下你的FF是否也为我添加的小提琴崩溃吗?我用你的小提琴尝试了相同的图像集。@SanchitMehta不,我从未能从你给的小提琴上重现你的FF崩溃,即使是40*5MB的图片。你收到我的留言了吗在崩溃前的控制台中?您是否尝试过逐个加载每个图像以查看是否有一个文件可能是原因?您的FF是否已更新?我确实尝试过一次加载一个图像。尝试使用300*5 MB图像。我相信您会看到错误。同样在IE11中,脚本在某些时间后停止执行