I'm using jquery and backbone.js on a site that is pretty image heavy. The core functionality of the site involves many many fairly small images (150x180px jpg files). The list of images comes in via ajax/json using a backbone.js collection fetch. Then for each model in the collection there is a view that gets rendered which contains an img element. The view is then added to the dom.
There is one user in particular that has thousands of images - a super edge-case relative to how many images most of our normal users have. When this user's image data loads, the browser just can't handle loading all the images, at least in the way our current code works. About half of the images load okay eventually, but the browser (i'm using chrome 35) becomes unresponsive for several minutes. The other half of the images fail to load, and the browser console shows "net::ERR_INSUFFICIENT_RESOURCES" errors for the images that don't load.
Here is the essential part of our code that loads the images. Can anyone provide an explanation as to technically why this image loading failure happens, and offer a solution that doesn't involve adding paging or "click her to load more" functionality to the image list?
// 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); }
And the render() code for the App.View.ImageView view:
render: function () { var renderedTemplate= theTemplate(this.model.toJSON()); this.$el.html(renderedTemplate); return this; }
And the template used by App.View.ImageView (this gets compiled only once using _.template):
<script type="text/template" id="thumb-template"> <a href="<%= ImageUrl%>"><img src="<%= ImageUrl%>" /></a> <div class="delete"></div> </script>
I believe this is the bug affecting you: https://bugs.chromium.org/p/chromium/issues/detail?id=108055
There's been discussion about it from 2011-2016, and is ongoing. Basically Chrome can't handle a very large number of requests in a short period of time.
Here's what helped a bit for my app:
img.addEventListener("error",tryAgainLater)
but that won't rescue the other resources that fail to load, so your script that loading hundreds of images could interfere with others.Here's what did not work:
Yet to try:
<img width="16" height="16" alt="star" src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />
The method toJSON() is very expensive for the browsers as it clones the 'attributes' in the model to return a JSON representation.
... // Return a copy of the model's `attributes` object. toJSON: function(options) { return _.clone(this.attributes); }, ...
In some scenarios where I just wanted to display the information of my model, I simply used the 'attributes' property directly, it saves very good time of processing.
Try replacing this line in the ImageView file:
theTemplate(this.model.toJSON());
for
theTemplate(this.model.attributes);
Hope this information helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With