2017-05-17 13 views
1

私は、ツイートのリストを表示するバックボーンdemo appで作業しています。私は$.html()

render: function() { 
    $("#item-table").html(''); 
    this.collection.each(this.addItem); 
} 

を使用してリストをクリアし、異なるデータを持つすべての「つぶやき」を交換していたよう誰かが私に私が原因$.html()を使用することにより、パフォーマンスを向上させるため、この$.html()を置き換えることができるものとヒントを与えることができれば、私は思っていました私はリフローを引き起こしており、レイアウト処理に時間がかかります。

コード内には$.html()という2つの場所がありますが、他の場所でも可能な場合でも誰かに教えてもらえると助かります。

答えて

3

Create新しいDocumentFragmentをすべてレンダリングしてから、DOMを一度更新します。

さらに、this.$(...)をグローバルjQueryセレクタ$(...)よりも優先してください。

this.$は、より効率的で、ビューの外で何かを選択しにくいthis.$el.find(...)へのプロキシです。

ビューがまだレンダリングされていなければ、ビュー内でjQueryのコア機能($())を使用すると失敗する可能性があります。したがって、常にthis.$elを操作する方が良いので、ビューが実際にDOMに配置される前でも変更を加えることができます。

アレイ内に作成されたすべてのサブビューを後で完全に削除するようにします。

initialize: function() { 
    this.childViews = []; 
}, 
render: function() { 
    // cache the list jQuery object 
    this.$list = this.$("#item-table"); 

    // Make sure to destroy every child view explicitely 
    // to avoid memory leaks 
    this.cleanup(); 

    this.renderCollection(); 
    return this; 
}, 

ここでは、一時的なコンテナを使用して実際の最適化を開始します。

renderCollection: function() { 
    var container = document.createDocumentFragment(); 

    this.collection.each(function(model) { 
     // this appends to a in memory document 
     container.appendChild(this.renderItem(model, false).el); 
    }, this); 

    // Update the DOM only once every child view was rendered. 
    this.$list.html(container); 
    return this; 
}, 

当社renderItem機能はまだ単一アイテムビューをレンダリングし、すぐにDOMでそれを置くために使用することができます。しかし、それはまた、DOM操作を延期するオプションを提供し、それは単にビューを返します。ダングリングリスナーにメモリリークを回避するために

renderItem: function(model, render) { 
    var view = new Item({ model: model }); 

    this.childViews.push(view); 
    view.render(); 
    if (render !== false) this.$list.append(view.el); 
    return view; 
}, 

、それはそれについて忘れて前に各ビューにremoveを呼び出すことが重要です。

実際の呼び出しをremoveに延期して追加の最適化を行うので、ユーザーが待機中に時間を無駄にしません。

cleanup: function() { 
    var _childViewsDump = [].concat(this.childViews); 
    this.childViews = []; 

    while (_childViewsDump.length > 0) { 
     var currentView = _childViewsDump.shift(); 
     // defer the removal as it's less important for now than rendering. 
     _.defer(currentView.remove.bind(currentView), options); 
    } 
} 
+0

ありがとうございます! React(仮想DOM)と比較してこのアプリのベンチマークを行い、KVO(Key-Value観察)ビューモデルの同期メカニズムの例として、このBackboneアプリを使用しています。私はただ確実にしたい - 私はこれらの最適化を実装する場合、このアプリはまだKVOのビューモデルの同期メカニズムの良い例になりますか? – gfels

+0

@gfels申し訳ありませんが、私はKVOビューモデルの同期メカニズムに精通していません。バックボーンのレンダリングとReactの比較に関しては、バックボーンはレンダリングを提供していないので、それは無関係であり、開発者は自分が好きなものを使用することができます。バックボーンはデフォルトでjQueryのみを提供していますが、デベロッパーはアプリのレンダリングを実装することができます。 –

+0

@gfels @KVOビューモデルの同期メカニズム_によって、双方向データバインディングを意味する場合、Backboneもそれを提供せず、Backboneで簡単に使用できるこのライブラリに特化したライブラリがあります。 (エポキシ、ノックアウト、バックボーン。スティッチ、さらにはリアクトを使うことができます) –

関連する問題