2013-07-03 15 views
18

私はFileReaderを使用して、バックボーンアプリケーションにローカルイメージを表示しています。小さな画像は問題なくすぐに表示されますが、画像が数メガバイト以上の場合は、画像を読み込むのに2〜3秒間かかります(MacBook Pro 8 GB RAM搭載)。ローカルイメージをブラウザに読み込む際のパフォーマンスの問題

コメントに指摘されているように、大きな画像は瞬間的にthis File API tutorialに読み込まれるため、問題はFileReaderではなく、私の具体的なバックボーンの実装であります。

関連するバックボーンモデルとビューを以下に示しました。論理の概要を次に示します。

  1. このモデルでは、ファイルパスが渡される新しいFileReaderが作成されます。
  2. ファイルがロードされると、Imageが作成され、ImagesrcFileReaderによって提供されるデータURLに設定されます。
  3. イメージがロードされると、モデルはイメージの幅と高さ(アプリケーションの別の場所で使用されます)で更新され、モデルのinitialized属性はtrueに設定されます(したがって、モデルではchangeイベントが発生します)。
  4. ビューでモデル上の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のソリューションよりも効率的に画像のサイズを変更することができるだろうと想定していたが、この仮定が間違っていた

Chrome Timeline

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

答えて

7

FileReaderを使用して大きな画像を読み込むときに同じ問題が発生しました。フルサイズで表示する予定がない場合は、canvas要素を使用してイメージを表示する前に、イメージを拡大縮小することをお勧めします。

自分で実装してもうまくいってから、JavaScript Load Image(MITライセンス)とそのmaxWidthオプションを使用することを選択しました。

the demoを試して、画像がうまく読み込まれているかどうかを確認してください。

+1

これはまさに問題でした。私は、JavaScriptソリューションを呼び出すのではなく、ブラウザのイメージのサイズをより効率的にすることを前提としていました。しかし、そうではありません。画像が表示される前に画像のサイズを変更することで、ラグを完全に排除しました。このシナリオでは、あなたが提案したプラグインは絶対に完璧です。ありがとう! –

+0

私はあなたのために働いてうれしいです、努力のためのhttps://github.com/blueimpへの名誉! – lazd

関連する問題