我正在使用FileReader在Backbone应用程序中显示本地图像。较小的图像立即显示没有任何问题,但当图像是几兆字节或更大时,Chrome需要2或3秒才能加载图像(在具有8 GB RAM的全新MacBook Pro上)。
正如评论中所指出的,大型图片会在this File API tutorial中即时加载,因此问题不在于FileReader
,而在于我在Backbone中的特定实现。
我在下面列出了相关的Backbone模型和视图。这是逻辑的概述:
FileReader
文件路径。Image
,并src
的{{1}}设置为Image
提供的数据网址。FileReader
属性设置为initialized
(因此触发)模型上的true
事件。)change
事件时,会调用change
函数,该函数会将render
的背景图像替换为数据网址。Backbone Model
div
主干视图
var PhotoModel = Backbone.Model.extend({
initialize: function() {
this.set({"available": true});
this.initialized = false;
if (this.get("file")) {
this.uploadPhoto();
}
},
uploadPhoto: function() {
var file = this.get("file");
var reader = new FileReader();
var model = this;
reader.onload = function(event) {
var image = new Image();
image.onload = function() {
model.set({width: this.width, height: this.height});
model.set("initialized", true);
};
image.src = event.target.result;
model.set("dataURL", event.target.result);
}
reader.readAsDataURL(file);
},
});
以下是Chrome时间轴的屏幕截图。数据URL请求和加载事件之间似乎发生了最大的延迟(这约占0.5秒)。我不确定“重新计算风格”究竟是什么。我也不确定为什么有这么多的油漆事件(它似乎在滚动条区域呈现)。
解
我曾假设浏览器能够比任何JavaScript解决方案更有效地本地调整图像大小,但这个假设是错误的。通过在显示之前调整图像的大小,我能够将延迟减少到 50毫秒。我使用了一个名为JavaScript Load Image的开源插件来处理图像加载和调整大小(它使用HTML5 var PhotoFormView = Backbone.View.extend({
className: "photo-form",
initialize: function() {
this.listenTo(this.model, "change", this.render);
this.render();
},
render: function() {
$(this.el).find(".photo").css({"background-image": "url(" + this.model.get("dataURL") + ")"});
},
});
标记)。这是我修改过的Backbone模型:
canvas
答案 0 :(得分:7)
使用FileReader加载大图像时遇到了同样的问题。如果您不打算以全尺寸显示它们,似乎解决方法涉及在使用canvas
元素显示图像之前缩放图像。
在我自己的实现取得了成功之后,我选择使用JavaScript Load Image(MIT许可证)及其maxWidth
选项,这解决了这个问题以及更多(不可预见的)问题。
尝试the demo,看看你的图片是否加载得很好。