我有一个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;
}
});
答案 0 :(得分:5)
这完全取决于用户需要什么样的经验,他将如何处理这些工作, 您的用户,是否正在寻找某份工作的潜在求职者? 或者它是一种管理应用程序,用户是管理工作的人吗?
一般情况下,在1页上放置1000个项目是糟糕的使用经验,在向下滚动下加载其他工作是一种热门功能,如Facebook,Twitter ......这可能对评论有好处,但工作是另外的,一个人需要一种从头到尾跳跃的方法,而不必点击“更多”10次,或者向下滚动10次。
可能的解决方案:
纯技术解决方案:
你应该阅读this blog post,如果你只是在一个视图中渲染了一个集合的所有项目,那么它开始是如何从一个视图中获取精确点击的项目,但是在这里演变为手头的问题, 每个作业有1000个单独的视图1被添加到jobListView,或者在jobListView中添加了这些作业,因此只有1个视图。
后者可以正确实施,大大减少您的应用与DOM的互动。正确实现后,我的意思是,在for循环中添加所有作业,将它们添加到内存中的表/列表中,并且仅在最后,将表/列表附加到DOM中,这会将代码减少为1 DOM交互而不是1000个附加。
是的,Derick确实更倾向于为每个模型渲染1个视图,尽管他没有触及性能主题,除了一小部分:首先让它快速声明,然后不为你提供任何解决方案。如果您的工作列表只是一个列表和一个到工作详细信息页面的链接,没有很多事件,则1视图统治它们所有选项仍然非常有效。
答案 1 :(得分:2)
您的糟糕表现可能是因为您直接向DOM添加了行。每次执行此操作时,浏览器都将重排。
我会在内存中构建表,然后在构造完成后将整个表添加到DOM中。