7

#each ヘルパーまたは Ember.ArrayController の計算されたプロパティにバインドされたコレクション ビューを使用してアイテムのリストをレンダリングすると、パフォーマンスの問題が発生します。10 から 20 項目の小さなリストではパフォーマンスは問題ありませんが、50 から 100 あたりではかなり著しく遅れが生じ始めます。いくつかの Todo にチェックを入れるか、[Todo を追加] をクリックしてみてください

サンプルコードはこちら: http://jsfiddle.net/Jonesy/ed3ZS/4/

変更のたびに DOM の childViews が再レンダリングされることに気付きました。これは、現時点では意図した動作である可能性が非常に高いですが、未完成の todo リストの DOM から todo を削除できるようにしたいと考えています。個別に作成し、完成した todo リストの最後に追加します。これは、理論的にははるかにコストがかかりません。

私が答えたいと思っているのは、Ember コレクション ビューのパフォーマンスの問題を見ているのか、計算されたプロパティから入力されたリストを表示するのは悪い考えなのかということです。もしそうなら、todo モデルの場所を手動で管理する必要がありますか?ビューレイヤーで、未完成から完成に、またはその逆に変化します。

4

1 に答える 1

13

{{#each}}これは、どのように機能するか(そしてCollectionView、それが機能するもの)の副作用です。

内部的には、配列オブザーバーCollectionViewと呼ばれるものを使用します。配列オブザーバーを使用すると、の変更メソッド ( 、、など)を使用して配列に対して行われた変更をサブスクライブできます。配列オブザーバーの API については、こちらで説明していますEmber.ArrayreplacepushObjectpopObject

これが意味することは、新しいオブジェクトをコレクション ビューにプッシュすると、DOM にレンダリング 1 つの新しい要素が挿入され、残りはそのまま残されるということです。

ただし、投稿した例では、配列は変更されていませんArray。新しいアイテムが追加または削除されるたびに、新しいオブジェクトを作成しています。バインドが同期されると、古い配列が新しい配列に置き換えられます。{{#each}}、これはすべての要素を削除してから追加し直すことと同じです。

この問題の解決策は、変更されるたびに異なる配列オブジェクトを返す計算プロパティではなく、単一の配列を使用することです。これを行う方法の例については、連絡先アプリを参照してください。

明らかに、これは非常に一般的なパターンであり、将来的にはデフォルトで正しいことを行う何らかのフィルタリングを追加したいと考えていますEmber.ArrayController

于 2012-05-29T08:00:07.857 に答える