使用$ .html()时如何提高渲染性能
我正在开发一个显示推文列表的Backbone 演示应用程序 。 当我用不同的数据替换所有“推文”时,我使用$.html()
清除列表
render: function() { $("#item-table").html(''); this.collection.each(this.addItem); }
我想知道是否有人可以给我一个提示,我可以替换这个$.html()
以获得更好的性能,因为使用$.html()
我会导致回流,并且会给出错误的布局处理时间。
代码中还有另外两个地方,我使用$.html()
,如果有人可以给我建议如果那些其他地方甚至是可能的话也会改变它们,这真的很棒。
创建一个新的DocumentFragment以预渲染所有项目,然后更新DOM一次。
另外,在全局jQuery选择器$(...)
。 $(...)
。
this.$
是这个的代理this.$el.find(...)
更有效率,更不容易选择视图之外的东西。
如果视图尚未呈现,则在视图中使用jQuery的核心函数( $()
)可能会失败。 所以最好总是操纵this.$el
所以你甚至可以在视图实际放入DOM之前进行更改。
保持在数组中创建的所有子视图以便以后干净地删除它们。
initialize: function() { this.childViews = []; }, render: function() { // cache the list jQuery object this.$list = this.$("#item-table"); // Make sure to destroy every child view explicitely // to avoid memory leaks this.cleanup(); this.renderCollection(); return this; },
真正的优化从这里开始,带有一个临时容器。
renderCollection: function() { var container = document.createDocumentFragment(); this.collection.each(function(model) { // this appends to a in memory document container.appendChild(this.renderItem(model, false).el); }, this); // Update the DOM only once every child view was rendered. this.$list.html(container); return this; },
我们的renderItem
函数仍可用于呈现单个项目视图,并立即将其放入DOM中。 但它也提供了推迟DOM操作的选项,它只返回视图。
renderItem: function(model, render) { var view = new Item({ model: model }); this.childViews.push(view); view.render(); if (render !== false) this.$list.append(view.el); return view; },
为了避免与悬空侦听器发生内存泄漏,在忘记它之前调用每个视图上的remove
是很重要的。
我通过推迟实际调用来使用额外的优化,因此我们不会在用户等待时浪费时间。
cleanup: function() { var _childViewsDump = [].concat(this.childViews); this.childViews = []; while (_childViewsDump.length > 0) { var currentView = _childViewsDump.shift(); // defer the removal as it's less important for now than rendering. _.defer(currentView.remove.bind(currentView), options); } }