当我使用#each帮助器或绑定到Ember.ArrayController的某些计算属性的集合视图渲染项目列表时,我遇到了性能问题。性能很好,有一个10-20项的小清单,但大约50-100,它开始明显滞后。尝试检查几个待办事项或点击“添加待办事项”
示例代码在这里:http://jsfiddle.net/Jonesy/ed3ZS/4/
我注意到DOM中的childViews会随着每次更改而重新呈现,这很可能是目前的预期行为,但我更愿意能够从DOM中删除一个todo。未完成的待办事项列表单独并附加到完成的待办事项列表的底部,这在理论上会低得多。
我希望回答的是我是否在查看Ember集合视图的性能问题,或者显示从计算属性填充的列表是个坏主意,如果是,我是否需要手动管理todo模型在视图层中的位置,因为它从未完成变为完成,反之亦然。
答案 0 :(得分:13)
这是{{#each}}
(以及CollectionView
(它是什么能力)的工作方式的副作用。
在内部,CollectionView
使用名为数组观察者的东西。数组观察器允许您使用Ember.Array
的变异方法(replace
,pushObject
,popObject
等来订阅对数组所做的突变。 。)数组观察者的API is described here。
这意味着,如果您将一个新对象推入一个集合视图,它将在DOM中插入一个新元素,并将其余部分留在原位。
但是,在您发布的示例中,数组未发生变异 - 每次添加或删除新项目时,您都会创建一个全新的Array
对象。当绑定同步时,用新数组替换旧数组。要{{#each}}
,这与删除所有元素然后重新添加它们没有区别。
问题的解决方案是使用单个数组,而不是每次更改时返回不同数组对象的计算属性。您可以看到the Contacts app for an example of how to do this。
显然,这是一种非常常见的模式,我们希望添加某种过滤功能,默认情况下会做出正确的事情Ember.ArrayController
。