我有一个要展示的系列。
1. for each model in collection, create a View
2. append view.render().el
我发现view.render()需要很长时间,更具体地说
this.$el.html(this.template(data))
部分。
我需要加快速度,发现'DOM操作'很慢 所以我找了批处理渲染的方法,但没有找到太多。
问题1.
我想知道是否有办法批量处理并将最终的html附加到DOM而不将每一行附加到DOM?
(我怀疑这个。$ el.html()执行DOM操作。如果是这样,我可以以某种方式不在view.render()中执行this.$el.html()
调用,然后分配视图的el以减少DOM交互吗?)
问题2.
在客户端浏览视图时是否还有其他陷阱或性能阻碍?
修改
addAll: function() {
this.$('#thread-loop').html('');
var fragment = document.createDocumentFragment();
for (var i = 0; i < this.threads.length; i++) {
console.log('adding one');
var thread = this.threads.at(i);
var View = this.threadTypeToViewMap[thread.get('thread_type')];
var view = new View( {model: thread, forumSelector: this.forumSelector} );
fragment.appendChild(view.render().el);
}
this.$el.find('#thread-loop')[0].appendChild(fragment);
// this.threads.each(this.addOne, this);
},
实际上,我意识到我正在使用片段技术。
我更多地解决了这个问题,看起来当javascript对象具有冗长的属性(用户创建的数据)时,handlebar需要很长时间才能在template()调用中找到属性(或者我怀疑)。
答案 0 :(得分:1)
他们扩展Backbone以提供针对集合优化的视图(因此您可以在循环中创建DOM节点,并在完成后仅将它们添加到文档中)。这对你的表现非常有帮助。
至于问题2,会给你带来陷阱的事情是:
答案 1 :(得分:1)
骨干模板渲染速度很慢,因为默认情况下,它们使用JavaScript的with
结构来正确调整变量名称的范围。 Backbone模板的一个鲜为人知的特性允许您通过分配变量来放置所有数据(通常只是“数据”)来跳过这个相当大的性能损失:
var t = _.template('<%= data.x %>', null, {variable: 'data'});
template({x: 42});
而不是正常:
_.template('<%= x %>');
template({x: 42});
执行此操作,您将看到巨大的性能提升。这可能会立即解决您的性能问题。
基准:http://jsperf.com/underscore-template-function-with-variable-setting
答案 2 :(得分:0)
对于Q1 - &gt; 如果您的$ el已经不在dom中,您可以将所有$ el附加到Document Fragment中,然后立即将Document Fragment注入页面。 JQuery的John Resig撰写了一篇关于文档片段如何工作的精彩文章:http://ejohn.org/blog/dom-documentfragments
答案 3 :(得分:0)
您可以尝试使用doc片段的几件事:
1-如果要使用for循环,请在循环之前缓存长度。 var threadLength = this.threads.length;
2-那就是说,我会选择使用_.each而不是for循环。
3-如果你做2,应该很容易访问线程模型。我不知道使用get()是否有任何命中,但你可以直接访问model.attributes.thread_type。
3-您的模板是否已缓存?
4-为什么要两次更改#thread-loop的html?需要吗?如果您需要访问它两次,那么也缓存该选择器。