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

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

一般来说,在一个页面上放置1000个项目是不好的用户体验,在向下滚动时加载额外的作业是目前流行的功能,比如facebook、twitter。。。这可能对评论有好处,但乔布斯是另一回事,人们需要一种从开始跳到结束的方式,而不必点击"更多"10次或向下滚动10次。

可能的解决方案:

  1. 因此,寻呼当然是另一种选择,使用寻呼机是处理太多项目的一种防御方式,并为用户提供了一种从第1页跳到第10页而不经过其他9页的方法
  2. 你可以做的另一件事是内置过滤器,可以通过以下方式搜索工作:地点、公司、行业。。。这将减小始终可见的集合的大小

纯技术解决方案:

你应该读一下这篇博客文章,它从如何从一个视图中获得准确点击的项目开始,如果你只在一个视图里呈现了一个集合的所有项目,但它演变成了眼前的问题,将1000个单独的视图中的每个作业1个添加到jobListView中,或者将这些作业添加在jobListView内,因此只有1个视图。

后者如果实现正确,可以大大减少应用程序与DOM的交互。如果实现正确,我的意思是,通过将所有作业添加到内存中的表/列表中,并仅在最后将表/列表附加到DOM中,将代码减少到1个DOM交互,而不是1000个附加。

是的,Derick确实更倾向于为每个模型渲染一个视图,尽管他除了一个小问题之外,没有触及性能的主题:先制作,然后制作快速声明,这不会为您提供任何解决方案。如果你的作业列表只是一个列表和一个指向作业详细信息页面的链接,没有很多事件,那么1视图规则所有选项仍然非常有效。

您的性能不佳可能是因为您将行直接添加到DOM中。每次执行此操作时,浏览器都会回流。

我会在内存中构建表,然后在构建完整个表后将其添加到DOM中。

最新更新