Backbone.js fetch()大集合导致脚本冻结

6 javascript collections render fetch backbone.js

我有一个Jobs表视图,显示用户的所有作业.Jobs集合fetch()可能返回包含数千条记录.我运行了一个测试并在DB中插入了1000个Job记录,并对集合执行了fetch().但是,由于插入1000个DOM表行似乎导致浏览器冻结,因此浏览器处理1000条记录似乎太多了.

有没有更好的方法来优化行的呈现,以便它更快地执行?我知道你总是可以进行部分提取(每次用户滚动到屏幕底部时,最初获取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;
  }

});
Run Code Online (Sandbox Code Playgroud)

San*_*der 5

这一切都取决于用户需要什么样的经验,他将如何处理工作,您的用户,是否是寻找某项工作的潜在求职者?或者它是一种管理应用程序,用户是管理工作的人?

一般在1页上放1000个项目是糟糕的使用经验,在向下滚动下加载额外的工作是像Facebook,Twitter这样的热门功能...这可能对评论有好处,但工作是别的,需要一个无需点击"更多"10次,或向下滚动10次,从头到尾跳跃的方法.

可能的解决方案:

  1. 因此,分页当然是另一种选择,使用寻呼机是一种方法来处理太多的项目,并让人们从第1页跳到10而不通过其他9个.
  2. 您可以做的另一件事是构建过滤器,可以通过以下方式搜索作业:位置,公司,扇区......这将减少始终可见的集合的大小.

纯技术解决方案:

你应该阅读这篇博文,如果你只在一个视图中呈现了一个集合的所有项目,那么它开始是如何从一个视图中获取精确点击的项目,但是在这里演变为手头的问题,每个视图有1000个单独的视图作业被添加到jobListView,或者在jobListView中添加了这些作业,因此只有1个视图.

后者可以正确实施,大大减少您的应用程序与DOM的交互.正确实现后,我的意思是,在for循环中添加所有作业,将它们添加到内存中的表/列表中,并且仅在最后,将表/列表附加到DOM中,这会将代码减少为1 DOM交互而不是1000个追加.

是的,Derick确实更倾向于为每个模型渲染1个视图,尽管他没有触及性能主题,除了一小部分:首先使它成为快速声明而不为您提供任何解决方案.如果您的作业列表只是一个列表和一个链接到作业详细信息页面,没有很多事件,则1视图统治它们所有选项仍然非常有效.