向dom添加大量img元素时出现net :: ERR_INSUFFICIENT_RESOURCES错误

Raf*_*afe 22 javascript performance jquery backbone.js

我在一个图像很重的网站上使用jquery和backbone.js.该网站的核心功能涉及许多相当小的图像(150x180px jpg文件).图像列表通过ajax/json使用backbone.js集合提取.然后,对于集合中的每个模型,都会有一个包含img元素的渲染视图.然后将视图添加到dom中.

特别是有一个用户拥有数千个图像 - 相对于大多数普通用户拥有的图像数量而言,这是一个超级边缘的情况.加载此用户的图像数据时,浏览器无法处理加载所有图像,至少在我们当前代码的工作方式.大约一半的图像最终加载正常,但浏览器(我使用的是chrome 35)在几分钟内没有响应.另一半图像无法加载,浏览器控制台显示未加载图像的"net :: ERR_INSUFFICIENT_RESOURCES"错误.

这是加载图像的代码的基本部分.任何人都可以从技术上解释为什么会发生这种图像加载失败,并提供一个解决方案,不涉及添加分页或"点击她加载更多"功能到图像列表?

// inside the view that renders the images
render: function () {
    this.collection.each(this.addOne, this);    
    return this;
},
addOne: function (imgModel) {
    var imgView = new App.Views.ImageView({ model: imgModel});
    this.$el.append(imgView.render().el);
}
Run Code Online (Sandbox Code Playgroud)

以及App.View.ImageView视图的render()代码:

render: function () {
    var renderedTemplate= theTemplate(this.model.toJSON());
    this.$el.html(renderedTemplate);
    return this;
}
Run Code Online (Sandbox Code Playgroud)

App.View.ImageView使用的模板(这只使用_.template编译一次):

<script type="text/template" id="thumb-template">          
        <a href="<%= ImageUrl%>"><img src="<%= ImageUrl%>" /></a>
        <div class="delete"></div>
</script>
Run Code Online (Sandbox Code Playgroud)

Woo*_*tty 19

我相信这是影响你的错误:https://bugs.chromium.org/p/chromium/issues/detail?id = 108055

从2011年到2016年,它一直在讨论它,并且正在进行中.基本上,Chrome无法在短时间内处理大量请求.

这对我的应用有点帮助:

  • 您可以添加一个事件处理程序, img.addEventListener("error",tryAgainLater)但不会挽救无法加载的其他资源,因此加载数百个图像的脚本可能会干扰其他图像.
  • 尝试缓存更多图像以减少网络请求的数量.
  • 使用Firefox代替......显然无法告诉客户.

这是不起作用的:

  • 将图像合成到画布上并丢弃单个图像.这没有用,因为它与网络请求有关,而不是存储在内存中的图像.
  • 在上一个图像完全加载之前不启动下一个请求.也许这是因为连接实际关闭或从内存(或其他一些资源)中删除需要时间.

然而尝试:

  • 通过HTTP/2或SPDY加载图像,其中有许多请求但只有一个连接.
  • 在您的情况下,您可以内联图像以避免提出请求.来自https://css-tricks.com/data-uris/的示例:<img width="16" height="16" alt="star" src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />


小智 5

toJSON() 方法对于浏览器来说非常昂贵,因为它克隆模型中的“属性”以返回 JSON 表示。

...
// Return a copy of the model's `attributes` object.
toJSON: function(options) {
  return _.clone(this.attributes);
},
...
Run Code Online (Sandbox Code Playgroud)

在某些情况下,我只想显示模型的信息,我直接使用“attributes”属性,它节省了很好的处理时间。

尝试替换 ImageView 文件中的这一行:

theTemplate(this.model.toJSON());
Run Code Online (Sandbox Code Playgroud)

为了

theTemplate(this.model.attributes);
Run Code Online (Sandbox Code Playgroud)

希望这些信息有帮助。