Backbone.js fetch() большой коллекции приводит к зависанию скрипта

У меня есть представление таблицы Jobs, которое отображает все задания пользователя. Коллекция Jobs fetch() может потенциально возвращать тысячи записей. Я провел тест и вставил 1000 записей о заданиях в БД и выполнил fetch() для коллекции. Однако 1000 записей кажется слишком много для браузера, поскольку вставка 1000 строк таблицы DOM приводит к зависанию браузера.

Есть ли лучший способ оптимизировать рендеринг строк, чтобы он выполнялся быстрее? Я знаю, что вы всегда можете сделать частичную выборку (получить изначально 100 записей и дополнительно получать 100 записей каждый раз, когда пользователь прокручивает экран до нижней части), но я в целом против этой идеи, поскольку прокрутка вниз 100 записей и необходимость ждать 3-4 секунды, прежде чем отобразится еще 100 записей, кажется, приводит к плохому пользовательскому опыту.

Вот мой код:

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

});
6
задан 21 January 2012 в 14:12
поделиться