私はFileReaderを使用して、バックボーンアプリケーションにローカルイメージを表示しています。小さな画像は問題なくすぐに表示されますが、画像が数メガバイト以上の場合は、画像を読み込むのに2〜3秒間かかります(MacBook Pro 8 GB RAM搭載)。ローカルイメージをブラウザに読み込む際のパフォーマンスの問題
コメントに指摘されているように、大きな画像は瞬間的にthis File API tutorialに読み込まれるため、問題はFileReader
ではなく、私の具体的なバックボーンの実装であります。
関連するバックボーンモデルとビューを以下に示しました。論理の概要を次に示します。
- このモデルでは、ファイルパスが渡される新しい
FileReader
が作成されます。 - ファイルがロードされると、
Image
が作成され、Image
のsrc
がFileReader
によって提供されるデータURLに設定されます。 - イメージがロードされると、モデルはイメージの幅と高さ(アプリケーションの別の場所で使用されます)で更新され、モデルの
initialized
属性はtrue
に設定されます(したがって、モデルではchange
イベントが発生します)。 - ビューでモデル上の
change
イベントが検出されると、div
のバックグラウンドイメージをデータURLに置き換えるrender
関数が呼び出されます。
バックボーンモデル
var PhotoModel = Backbone.Model.extend({
initialize: function() {
this.set({"available": true});
this.initialized = false;
if (this.get("file")) {
this.uploadPhoto();
}
},
uploadPhoto: function() {
var file = this.get("file");
var reader = new FileReader();
var model = this;
reader.onload = function(event) {
var image = new Image();
image.onload = function() {
model.set({width: this.width, height: this.height});
model.set("initialized", true);
};
image.src = event.target.result;
model.set("dataURL", event.target.result);
}
reader.readAsDataURL(file);
},
});
バックボーンビューの下
var PhotoFormView = Backbone.View.extend({
className: "photo-form",
initialize: function() {
this.listenTo(this.model, "change", this.render);
this.render();
},
render: function() {
$(this.el).find(".photo").css({"background-image": "url(" + this.model.get("dataURL") + ")"});
},
});
はクロームタイムラインのスクリーンショットです。最大の遅延は、データURL要求と負荷イベントの間で発生するようです(これは約0.5秒です)。私は「再計算スタイル」が何であるかは分かりません。私はまた、なぜそれほど多くのペイントイベントがあるのかわかりません(それはスクロールバー領域でレンダリングされているようです)。私は、ブラウザがネイティブに任意のJavaScriptのソリューションよりも効率的に画像のサイズを変更することができるだろうと想定していたが、この仮定が間違っていた
SOLUTION
。 のサイズを変更すると、表示される画像はとなり、遅延は約50ミリ秒に縮小できました。私はJavaScript Load Imageと呼ばれるオープンソースのプラグインを使用して、イメージのロードとサイズ変更(HTML5 canvas
タグを使用)を処理しました。
var PhotoModel = Backbone.Model.extend({
initialize: function() {
this.set({available: true});
this.set({initialized: false});
if (this.get("file")) {
this.uploadPhoto();
}
},
uploadPhoto: function() {
var model = this;
loadImage(this.get("file"), function (img) {
model.set({img: img});
model.set({initialized: true});
}, {maxHeight: 344});
},
});
これはまさに問題でした。私は、JavaScriptソリューションを呼び出すのではなく、ブラウザのイメージのサイズをより効率的にすることを前提としていました。しかし、そうではありません。画像が表示される前に画像のサイズを変更することで、ラグを完全に排除しました。このシナリオでは、あなたが提案したプラグインは絶対に完璧です。ありがとう! –
私はあなたのために働いてうれしいです、努力のためのhttps://github.com/blueimpへの名誉! – lazd