2012-05-29 15 views
7

Si verifica un problema di prestazioni quando eseguo il rendering di un elenco di elementi utilizzando l'helper #each o una vista raccolta associata ad alcune proprietà calcolate di un Ember.ArrayController. Le prestazioni vanno bene con una piccola lista di 10 - 20 articoli, ma intorno ai 50 - 100 inizia ad essere piuttosto lento. Prova a controllare fuori qualche Todos o clic su "Aggiungi Todo"Emberjs Handlebars #each helper lento quando associato a proprietà calcolate

codice di esempio è qui: http://jsfiddle.net/Jonesy/ed3ZS/4/

ho notato che i childViews nel DOM ottenere ri-resi ad ogni cambio, che potrebbe benissimo essere il comportamento previsto al momento, ma preferirei essere in grado di rimuovere un todo dal DOM della lista dei todos incompiuta individualmente e aggiunto al fondo della lista dei prodotti finiti, che in teoria sarebbe molto meno costoso.

Quello che spero di avere una risposta è se sto esaminando un problema di prestazioni con le viste di raccolta Ember o se visualizzare un elenco popolato da una proprietà calcolata è una cattiva idea e, in tal caso, dovrò gestirlo manualmente la posizione del modello todo nel livello vista mentre passa da non finito a finito e viceversa.

risposta

13

Questo è un effetto collaterale di come funziona {{#each}} (e CollectionView, che è ciò che lo alimenta).

Internamente, CollectionView utilizza qualcosa chiamato osservatori di array. Un osservatore di array consente di sottoscrivere le mutazioni apportate a un array quando vengono eseguite utilizzando i metodi di mutazione Ember.Array (replace, pushObject, popObject, ecc.) L'API per gli osservatori di array is described here.

Ciò significa che, se si spinge un nuovo oggetto in una vista insieme, verrà inserito il rendering di un nuovo elemento nel DOM e si lascerà il resto in posizione.

Nell'esempio che hai pubblicato, tuttavia, l'array non viene modificato: crei un nuovo oggetto Array ogni volta che un nuovo elemento viene aggiunto o rimosso. Quando il binding si sincronizza, lo sostituisce il vecchio array con il nuovo array. Per {{#each}}, questo non è diverso da rimuovere tutti gli elementi e quindi aggiungerli nuovamente.

La soluzione al problema è utilizzare un singolo array, invece di una proprietà calcolata che restituisce un oggetto array diverso ogni volta che i cambiamenti. Puoi vedere the Contacts app for an example of how to do this.

Ovviamente questo è uno schema molto comune e vorremmo aggiungere qualche tipo di filtro che faccia la cosa giusta per impostazione predefinita su Ember.ArrayController lungo la strada.

+2

Questo è ancora il caso in Ember 1.0.0-RC.1 e si dispone di un esempio aggiornato? –

+0

@Tom, l'app contatti che hai collegato è morta ora. – adil

Problemi correlati