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);
Надеемся, что эта информация поможет.