私はかなり画像が重いサイトでjqueryとbackbone.jsを使用しています。サイトのコア機能には、非常に多くの非常に小さな画像(150x180px jpgファイル)が含まれます。画像のリストは、backbone.jsコレクションフェッチを使用してajax/json経由で取得されます。コレクション内の各モデルには、img要素を含むレンダリングされるビューがあります。その後、ビューがdomに追加されます。
特に、数千の画像を持っているユーザーが1人います。これは、通常のユーザーのほとんどが持っている画像の数に比べて、極端なエッジケースです。このユーザーの画像データが読み込まれると、少なくとも現在のコードが機能する方法では、ブラウザはすべての画像の読み込みを処理できません。画像の約半分は最終的には正常にロードされますが、ブラウザ(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);
}
そして、App.View.ImageViewビューのrender()コード:
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>
これがあなたに影響するバグだと思います: https://bugs.chromium.org/p/chromium/issues/detail?id=108055
2011年から2016年にかけて議論されており、現在も進行中です。基本的にChromeは短時間で非常に多くのリクエストを処理できません。
ここに何があります 少し助けた 私のアプリの場合:
img.addEventListener("error",tryAgainLater)
のようなイベントハンドラーを追加することはできますが、ロードに失敗した他のリソースをレスキューしないため、数百のイメージをロードするスクリプトが他のリソースに干渉する可能性があります。ここに何があります 動作しませんでした:
まだ試してみてください:
<img width="16" height="16" alt="star" src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />
メソッドtoJSON()は、モデル内の「属性」を複製してJSON表現を返すため、ブラウザーにとって非常に高価です。
...
// Return a copy of the model's `attributes` object.
toJSON: function(options) {
return _.clone(this.attributes);
},
...
モデルの情報を表示するだけのシナリオでは、単に「属性」プロパティを直接使用しただけで、非常に良い処理時間を節約できました。
ImageViewファイルの次の行を置き換えてみてください。
theTemplate(this.model.toJSON());
for
theTemplate(this.model.attributes);
この情報がお役に立てば幸いです。