Net:: ERR_INSUFFICIENT_RESOURCES ошибка при добавлении многочисленных элементов img в dom

Я использую jquery и backbone.js на сайте, который довольно тяжелый. Основная функциональность сайта включает в себя много довольно небольших изображений (файлы размером 150x180px jpg). Список изображений поступает через ajax/json с использованием коллекции backbone.js. Тогда для каждой модели в коллекции есть представление, которое получает rendered, которое содержит элемент img. Затем представление добавляется в dom.

Существует, в частности, один пользователь, который имеет тысячи изображений - супер-крайний случай относительно того, сколько изображений у большинства наших обычных пользователей. Когда эти данные изображения пользователя загружаются, браузер просто не может обработать загрузку всех изображений, по крайней мере, в том, как работает наш текущий код. Примерно половина изображений загружается в порядке, но браузер (я использую хром 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);
}

И код render() для представления App.View.ImageView:

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

И шаблон, используемый App.View.ImageView(он скомпилируется только один раз с использованием _.template):

<script type="text/template" id="thumb-template">          
        <a href="<%= ImageUrl%>"><img src="<%= ImageUrl%>" /></a>
        <div class="delete"></div>
</script>

Ответ 1

Я считаю, что это ошибка, влияющая на вас: https://bugs.chromium.org/p/chromium/issues/detail?id=108055

Обсуждалось это с 2011-2016 гг. и продолжается. В основном Chrome не может обрабатывать очень большое количество запросов за короткий промежуток времени.

Здесь помогло немного для моего приложения:

  • Вы можете добавить обработчик событий, например img.addEventListener("error",tryAgainLater), но это не спасет другие ресурсы, которые не загружаются, поэтому ваш script, который загружается сотни изображений могут помешать другим.
  • Попробуйте кэшировать больше изображений, чтобы уменьшить количество сетевых запросов.
  • Использовать 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" />

Ответ 2

Метод toJSON() очень дорог для браузеров, поскольку он клонирует "атрибуты" в модели, чтобы вернуть представление JSON.

...
// Return a copy of the model `attributes` object.
toJSON: function(options) {
  return _.clone(this.attributes);
},
...

В некоторых сценариях, где я просто хотел отобразить информацию о моей модели, я просто использовал свойство "attributes" напрямую, это экономит очень хорошее время обработки.

Попробуйте заменить эту строку в файле ImageView:

theTemplate(this.model.toJSON());

для

theTemplate(this.model.attributes);

Надеемся, что эта информация поможет.