【发布时间】:2016-01-08 07:09:32
【问题描述】:
我正在创建一个应该能够接受至少 1000 张图片的图片上传器。用户选择/拖放图像后,应显示图像以进行预览。然后,用户将点击上传按钮开始上传。
我已经实现了整个功能,它可以在 Chrome 上运行,就像一个魅力。但这在 Firefox 中失败了。
我创建了一种排队机制,一旦用户选择图像,在某个时间点只有 n 个图像会加载到浏览器中。
超过 20 张图像也会发生崩溃(即使使用排队机制创建一批 1 张图像)。我在 Firefox 中使用 Tab Memory Usage Plugin(http://mybrowseraddon.com/tab-memory.html) 检查了内存使用情况。它甚至会因 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);
}
当我评论以下代码时,Firefox 不会崩溃 ctx.drawImage(img, 0, 0, width, height)
所以到目前为止,我认为问题出在这个 drawImage 上。可能在 Chrome 和 Firefox 中 drawImage 的实现是不同的,我使用它的方式使它在 Chrome 中工作,但在 Firefox 中,它会引发错误。
有人对为什么会发生这个问题有任何具体的想法吗?
JSFiddle-http://jsfiddle.net/sanchit235/7xh1gbj6/
Firefox 崩溃报告-https://crash-stats.mozilla.com/report/index/6107c530-12a1-4aea-96c9-0366c2151010
【问题讨论】:
-
delete不会像您想的那样做。它只删除对象的属性,不删除对象引用(因此垃圾收集器不会回收对象的内存)。 -
删除在这里几乎没有意义。我添加它只是为了确定。这里的所有变量都是本地的。因此,理想情况下,它们将被自己收集垃圾。如果其中一些由于我使用它们的方式一定会导致泄漏,请告诉我。
-
当你不做这些无用的清洁时,是否也会发生这种情况?
-
即使我正在做这种无用的清洁,它也会发生;) 顺便说一句,如果没有这种无用的清洁,chrome 就会给 Aww Snap。所以我不得不这样做。
-
对我来说,这似乎不是解决您的“aw snap”问题的正确解决方案。如果我认为它的发生是因为您的代码使页面无响应是正确的,那么您可以尝试
requestAnimationFrame限制。我现在甚至没有时间重现错误,所以我无法判断它是否会起作用,但它应该给浏览器时间来处理每个对象和垃圾收集。
标签: javascript jquery html firefox canvas