Emberjs Handlebars # helper slow when bound to computed properties

I am having a performance issue when rendering a list of items using the #each helper or a collection view tied to some of the computed properties of Ember.ArrayController. Performance is excellent with a small list of 10 to 20 items, but around 50 to 100 it starts to lag noticeably. Try checking out a few todos or by clicking "Add Todo"

Sample code here: http://jsfiddle.net/Jonesy/ed3ZS/4/

I noticed that childViews in the DOM come back with every change, which may well be the intended behavior at the moment, but I would prefer that I just had to remove the todos from the DOM from the incomplete todos list individually and added to the bottom of the todos ready list, which theoretically would be much less expensive.

To which I hope to get an answer: am I viewing a performance problem with Ember collection views or displaying a list from a computed property as a bad idea, and if so, I need to manually manage todo in the viewport as it changes from unfinished to finished and vice versa.

+7
source share
1 answer

This is a side effect of how {{#each}} (and CollectionView , which is its power).

Inside CollectionView , something called array watchers is used. An array observer allows you to subscribe to mutations made for an array when they are performed using the Ember.Array mutation Ember.Array ( replace , pushObject , popObject , etc.) The API for array observers is described here .

This means that if you insert a new object into the collection view, it will insert one new element into the DOM and leave the rest in place.

In the above example, the array does not mutate - you create a new Array object each time a new element is added or deleted. When the binding is synchronized, it replaces the old array with the new array. For {{#each}} this is no different than deleting all elements and then adding them back.

The solution to this problem is to use a single array instead of a computed property that returns each object of the array each time it changes. You can see the Contacts app for an example of how to do this .

Obviously, this is a very common template, and we would like to add some kind of filtering, which by default does Ember.ArrayController by default.

+13
source

All Articles