2012-01-21 10 views
6

私は、ユーザーのすべてのジョブを表示するジョブテーブルビューを持っています。 Jobsコレクションfetch()は、何千ものレコードを含む可能性があります。私はテストを実行し、1000のジョブレコードをDBに挿入し、コレクションに対してfetch()を実行しました。しかし1000のレコードを挿入するとブラウザがフリーズするように見えるので、1000レコードはブラウザが扱うには多すぎるようです。Backbone.js fetch()大きなコレクションによってスクリプトがフリーズする

行のレンダリングを最適化して高速化する方法はありますか?私はあなたがいつも部分的なフェッチを行うことができる(最初の100レコードをフェッチし、さらにユーザが画面の下にスクロールするたびに100レコードをフェッチすることができる)ことを知っていますが、100レコードをスクロールして3追加の100レコードをレンダリングする前に-4秒かかると、ユーザーエクスペリエンスが低下するようです。

ここに私のコードです:

FM.Views.JobTable = Backbone.View.extend({ 
    initialize: function(){ 
    _.bindAll(this, 'render', 'refresh', 'appendItem'); 
    this.collection.bind('add', this.appendItem, this); 
    this.collection.bind('reset', this.refresh, this); 
    }, 

    render: function(){ 
    this.el = ich.JobTable({}); 
    $(this.el).addClass('loading'); 
    return this; 
    }, 

    refresh: function(){ 
    $('tbody tr', this.el).remove(); 
    $(this.el).removeClass('loading'); 

    _(this.collection.models).each(function(item){ // in case collection is not empty 
     this.appendItem(item); 
    }, this); 
    return this;  
    }, 

    appendItem: function(item){ 
    var jobRow = new FM.Views.JobTableRow({ 
     model: item 
    }); 
    $('tbody', this.el).prepend(jobRow.render().el); 
    $(jobRow).bind('FM_JobSelected', this.triggerSelected); 
    } 

}); 

FM.Views.JobTableRow = Backbone.View.extend({ 
    tagName: 'tr', 

    initialize: function(){ 
    _.bindAll(this, 'render', 'remove', 'triggerSelected'); 
    this.model.bind('remove', this.remove); 
    }, 

    render: function(){ 
    var j = this.model.toJSON(); 
    j.quantity = j.quantity ? number_format(j.quantity, 0) : ''; 
    j.date_start = date('M j Y', j.date_start); 
    j.date_due = j.date_due ? date('M j Y', strtotime(j.date_due)) : ''; 
    j.paid_class = j.paid; 
    j.status_class = j.status; 
    j.paid = slug2words(j.paid); 
    j.status = slug2words(j.status); 

    this.el = ich.JobTableRow(j); 
    $(this.el).bind('click', this.triggerSelected); 
    return this; 
    } 

}); 

答えて

5

それはすべてのユーザーが必要とするものの経験に依存し、どのような彼は仕事、 ユーザーで行う必要があります、それが探している潜在的な仕事の候補であります特定の仕事ですか? か、ユーザーが仕事を管理している管理アプリのようなものでしょうか?

一般的に1ページに1000個のアイテムを置くことは悪いuserexperienceです。スクロールダウンで追加のジョブを読み込む作業は、最近のフェイスブック、ツイッターなどのホットな機能のようなものです...これはコメントには良いかもしれませんが、 「more」を10回クリックしたり、10回スクロールしたりすることなく、最初から最後までジャンプする方法が必要です。

可能な解決策:

  1. ので、ページングは​​もちろん別のオプションで、ポケットベルを使用してdefenatelyあまりにも多くのアイテムと連携するための方法である、と人にすることなく、10に1ページからジャンプするための方法を与えます9つの他のものを通る。
  2. 別のことは、フィルタをビルドすることです。場所、会社、セクターなどでジョブを検索できます。これにより、常に表示されるコレクションのサイズが縮小されます。

純粋な技術的解決策:

あなたはthis blog post上に読んでください、それはあなたがちょうど1ビューでコレクションのすべての項目をレンダリングした場合、ビューからの正確なクリックした項目を取得する方法については始まりますが、に進化ここでの問題 は、ジョブごとに1つのビュー1が1つずつjobListViewに追加されているか、jobListView内にジョブが追加されているため、1つのビューしかありません。

正しく実装されていれば、アプリケーションとDOMのやりとりを大幅に減らすことができます。正しく実装されているとは、forループ内のすべてのジョブをメモリ内のテーブル/リストに追加すること、そして最後にのみテーブル/リストをDOMに追加することです。 、1000個の付加ではなく。

はい、Derickはモデルごとに1つのビューをレンダリングするためにもっと傾いていますが、小さなものを除いてパフォーマンスのテーマには触れません。まず、それを速いステートメントにして解決策を提供しません。あなたの仕事のリストが単なるリスティングであり、多くのイベントなしで仕事の詳細ページへのリンクであれば、それらをすべて支配するための1つの選択肢は依然として非常に有効です。

+0

私はブログ記事でこの例を試しましたが、実際にはパフォーマンスをあまり改善していないようです。 DOMに追加するか、メモリ内の要素に追加するかにかかわらず、あなたはまだjQueryのappend()を1000回呼びます。 – peter

+0

yesしかし、jqueryをdom自体に追加するのではなく、もっと速くなります。それでも、もっと良い解決策があります。それはもっと汚れて見えるかもしれませんが、手動で(またはテンプレートで)HTMLを構築し、$(elem).html(myBuildUpHtmlString);を実行してください。あなたが1000の追加を持っていない場合はさらに高速です。 – Sander

2

DOMに直接行を追加しているため、パフォーマンスが低下している可能性があります。これを行うたびに、ブラウザはリフローされます。

私はメモリにテーブルを構築し、そのテーブルを構築した後にDOMにテーブル全体を追加します。

関連する問題