2014-06-09 3 views
11

Ich benutze jquery und backbone.js auf einer Website, die ziemlich Bild schwer ist. Die Kernfunktionalität der Website beinhaltet viele, ziemlich kleine Bilder (150x180px jpg-Dateien). Die Liste der Bilder kommt über AJAX/JSON mit einem Backbone.js Collection Fetch. Dann gibt es für jedes Modell in der Sammlung eine Ansicht, die gerendert wird und ein img-Element enthält. Die Ansicht wird dann zum Dom hinzugefügt.net :: ERR_INSUFFICIENT_RESOURCES Fehler beim Hinzufügen zahlreicher IMG-Elemente zu Dom

Es gibt einen Benutzer, der tausende von Bildern hat - ein Super-Edge-Case, relativ zu wievielen Bildern die meisten unserer normalen Benutzer haben. Wenn die Bilddaten dieses Benutzers geladen werden, kann der Browser das Laden aller Bilder nicht verarbeiten, zumindest nicht so, wie unser aktueller Code funktioniert. Ungefähr die Hälfte der Bilder wird schließlich geladen, aber der Browser (ich verwende Chrom 35) reagiert für einige Minuten nicht mehr. Die andere Hälfte der Bilder wird nicht geladen und die Browserkonsole zeigt "net :: ERR_INSUFFICIENT_RESOURCES" -Fehler für die Bilder an, die nicht geladen werden.

Hier ist der wesentliche Teil unseres Codes, der die Bilder lädt. Kann jemand erklären, warum dieser Bildladefehler auftritt, und eine Lösung anbieten , die kein Hinzufügen von Paging oder "Klick sie, um mehr zu laden" -Funktionalität in die Bildliste?

// 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); 
} 

Und die render() Code für die App.View.ImageView Ansicht:

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

Und die Vorlage verwendet von App.View.ImageView (dies ist nur einmal kompiliert wird mit _.template) :

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

Stellt sich heraus, dass, obwohl es unglaublich langsam ist, so viele Bilder zu laden, der seltsame Fehler kam von AdBlock Plus. Ich habe das chrome-plugin deaktiviert und die Fehler sind verschwunden, und die Bilder werden geladen ... dauert nur eine lange Zeit, bis der Browser die Seite gerendert hat und alle Arbeiten erledigt, die der Browser unter der Haube erledigen muss. – Rafe

+0

Ich weiß, du hast gesagt, du willst keine "Klick hier, um mehr zu laden" Lösung, aber ich habe die gleiche Situation und ich denke, unendliches Scrollen ist wahrscheinlich die beste Option. Es macht auch Sinn. Warum zwingen Sie den Browser, 8k Bilder gleichzeitig zu rendern, wenn nur ~ 20 von ihnen gleichzeitig gesehen werden? – djKianoosh

+0

@djKianoosh In meinem Fall werden die Bilder gekachelt und visuell mit Isotope gefiltert. Sie können auf der Clientseite keine Objekte sortieren/filtern, die nicht geladen sind. Daher müssen alle Objekte geladen sein. – Rafe

Antwort

3

Verfahren toJSON() ist sehr teuer für den Browser, wie es Klone, die die ‚Attribute‘ in dem Modell eine Darstellung JSON zurückzukehren.

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

In einigen Szenarien, in denen ich wollte nur die Informationen meines Modells anzuzeigen, habe ich einfach die ‚Attribute‘ Eigenschaft direkt, sondern spart sehr gute Zeit der Verarbeitung.

Versuchen Sie diese Zeile in der Imagedatei zu ersetzen:

theTemplate(this.model.toJSON()); 

für

theTemplate(this.model.attributes); 

Hoffnung diese Informationen helfen.

7

Ich glaube, das der Fehler ist es, Sie zu beeinflussen: https://bugs.chromium.org/p/chromium/issues/detail?id=108055

Es gab Diskussionen darüber 2.011-2.016, und ist noch nicht abgeschlossen. Grundsätzlich kann Chrome eine sehr große Anzahl von Anfragen in kurzer Zeit nicht verarbeiten.

Hier ist, was half ein wenig für meine App:

  • Sie können einen Event-Handler wie img.addEventListener("error",tryAgainLater) hinzufügen, aber das wird die anderen Ressourcen nicht retten, die nicht geladen werden, so dass Ihr Skript, dass das Laden Hunderte von Bildern könnten andere stören.
  • Versuchen Sie, mehr Bilder zwischenzuspeichern, um die Anzahl der Netzwerkanforderungen zu reduzieren.
  • Verwenden Sie stattdessen Firefox ... offensichtlich kann Kunden das nicht sagen.

Hier ist, was nicht funktionierte:

  • auf einer Leinwand die Bilder Compositing und die einzelnen Bilder zu verwerfen. Dies half nicht, da es sich auf die Netzwerkanforderungen bezieht, nicht auf die im Speicher abgelegten Bilder.
  • Die nächste Anforderung wird erst gestartet, wenn das vorherige Bild vollständig geladen ist. Vielleicht liegt es daran, dass es Zeit braucht, bis die Verbindung tatsächlich geschlossen wird oder aus dem Speicher (oder einer anderen Ressource) entfernt wird.

Doch versuchen:

  • die Bilder über HTTP/2 oder SPDY Laden, wo es viele Anfragen sind aber nur eine Verbindung.
  • In Ihrem Fall könnten Sie die Bilder wahrscheinlich inline einfügen, um Anfragen zu vermeiden. Beispiel von https://css-tricks.com/data-uris/: <img width="16" height="16" alt="star" src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />
+1

Hallo, FYI Ich habe versucht "Laden Sie die Bilder über HTTP/2, wo es viele Anfragen gibt, aber nur eine Verbindung." aber das führt zu demselben Problem. Mein Test HTML versucht 10000 Bilder von 25x25 Pixel zu laden. – Rolf

+0

Einverstanden - wir haben auch versucht HTTP/2 und es hat nicht geholfen. – Meekohi

Verwandte Themen