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

Javascript 将本地图像加载到浏览器时出现性能问题,javascript,jquery,html,css,backbone.js,Javascript,Jquery,Html,Css,Backbone.js,我用它在主干应用程序中显示本地图像。较小的图像会立即显示,不会出现任何问题,但当图像达到数兆字节或更大时,Chrome需要2或3秒来加载图像(在配备8 GB RAM的全新MacBook Pro上) 正如在评论中指出的,大图像会立即加载,因此问题不在于FileReader,而在于我在主干网中的特定实现 我在下面介绍了相关的主干模型和视图。下面是逻辑的概要: 该模型创建一个新的文件读取器,将文件路径传递到该读取器中 加载文件后,将创建一个图像,并将图像的src设置为文件读取器提供的数据URL 加载图

我用它在主干应用程序中显示本地图像。较小的图像会立即显示,不会出现任何问题,但当图像达到数兆字节或更大时,Chrome需要2或3秒来加载图像(在配备8 GB RAM的全新MacBook Pro上)

正如在评论中指出的,大图像会立即加载,因此问题不在于
FileReader
,而在于我在主干网中的特定实现

我在下面介绍了相关的主干模型和视图。下面是逻辑的概要:

  • 该模型创建一个新的
    文件读取器
    ,将文件路径传递到该读取器中
  • 加载文件后,将创建一个
    图像
    ,并将
    图像
    src
    设置为
    文件读取器
    提供的数据URL
  • 加载图像后,将使用图像的宽度和高度(在应用程序中的其他位置使用)更新模型,并将模型的
    initialized
    属性设置为
    true
    (从而在模型上触发
    change
    事件)
  • 当视图在模型上检测到
    change
    事件时,将调用
    render
    函数,该函数用数据URL替换
    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);
      },
    });
    
    主干视图

    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") + ")"});
      },
    });
    
    下面是Chrome时间表的屏幕截图。最大的延迟似乎发生在数据URL请求和加载事件之间(约为0.5秒)。我不确定“重新计算样式”是什么意思。我也不确定为什么会有这么多绘制事件(它似乎是在滚动条区域渲染的)

    解决方案

    我曾经假设浏览器能够比任何JavaScript解决方案更有效地调整图像的大小,但是这个假设是错误的。通过在图像显示之前调整其大小,我能够将延迟减少到大约50毫秒。我使用了一个名为的开源插件来处理图像加载和大小调整(它使用HTML5
    canvas
    tag)。这是我修改后的主干模型:

    var PhotoModel = Backbone.Model.extend({
    
      initialize: function() {
        this.set({available: true});
        this.set({initialized: false});
        if (this.get("file")) { 
          this.uploadPhoto();
        }
      },
    
      uploadPhoto: function() {
        var model = this;
        loadImage(this.get("file"), function (img) {
          model.set({img: img});
          model.set({initialized: true});
        }, {maxHeight: 344});
      },
    });
    

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

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


    请尝试,看看您的图像加载是否良好。

    这正是问题所在。我认为浏览器在本机调整图像大小方面比调用JavaScript解决方案更有效。然而,事实并非如此。通过在显示之前调整图像的大小,我完全消除了延迟。您建议的插件非常适合此场景。谢谢我很高兴为你工作,为你的辛勤工作而感到荣幸!