将本地映像加载到浏览器时出现性能问题

时间:2013-07-03 03:36:03

标签: javascript jquery html5 css3 backbone.js

我正在使用FileReader在Backbone应用程序中显示本地图像。较小的图像立即显示没有任何问题,但当图像是几兆字节或更大时,Chrome需要2或3秒才能加载图像(在具有8 GB RAM的全新MacBook Pro上)。

正如评论中所指出的,大型图片会在this File API tutorial中即时加载,因此问题不在于FileReader,而在于我在Backbone中的特定实现。

我在下面列出了相关的Backbone模型和视图。这是逻辑的概述:

  1. 模型会创建一个新的FileReader文件路径。
  2. 加载文件后,系统会创建Image,并src的{​​{1}}设置为Image提供的数据网址。
  3. 图片加载后,模型会更新图像的宽度和高度(在应用程序的其他位置使用),模型的FileReader属性设置为initialized(因此触发)模型上的true事件。)
  4. 当视图在模型上检测到change事件时,会调用change函数,该函数会将render的背景图像替换为数据网址。
  5. 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秒)。我不确定“重新计算风格”究竟是什么。我也不确定为什么有这么多的油漆事件(它似乎在滚动条区域呈现)。

    Chrome Timeline

    我曾假设浏览器能够比任何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

1 个答案:

答案 0 :(得分:7)

使用FileReader加载大图像时遇到了同样的问题。如果您不打算以全尺寸显示它们,似乎解决方法涉及在使用canvas元素显示图像之前缩放图像。

在我自己的实现取得了成功之后,我选择使用JavaScript Load Image(MIT许可证)及其maxWidth选项,这解决了这个问题以及更多(不可预见的)问题。

尝试the demo,看看你的图片是否加载得很好。