2

foreach バインディングでレンダリングされた、50 個のアイテムを含む監視可能な配列があります。

if各アイテムがレンダリングするテンプレートがバインドに苦しんでいる理由を理解しようとしています。基本的に、計算されたオブザーバブルに基づいて、テンプレートの大部分を表示または非表示にしています。これにより、レンダリング時間が 70 ~ 100% 増加します (visible代わりにバインディングを使用する場合と比較して)。

このトピックに関するRyan Niemeyer の素晴らしい投稿は、計算されたものをifバインディングにバインドすると、計算されたものの一部が更新されるたびにすべてのコンテンツが再レンダリングされることを示しています。しかし、私の計算は、観測可能な配列がループされている間、値を変更しません。

this.filtersAvailable = ko.computed(function () { 
   return this.searchInfo.searchType() != 'invites' && this.searchInfo.searchType() != 'requests' 
}, this);

そして、実際に変更されていないことを確認するために、これを追加しました:

this.filtersAvailable.subscribe(function(newVal) { alert("fa" + newVal); });
this.searchInfo.searchType.subscribe(function(newVal) { alert("st" + newVal); });

そうは言っても、この計算、監視可能な配列の個々のビュー モデルよりも高いレベルで定義されており、テンプレートの他の場所と、もちろん監視可能な配列の他のすべての項目の両方で繰り返し 呼び出されます。

計算されたオブザーバブルをこのように繰り返し呼び出すifと、再レンダリングへのバインディングでそれにバインドされたものが発生しますか?

4

2 に答える 2

4

計算されたオブザーバブルの値に何度もアクセスしても問題はありません。キャッシュされた値が毎回返されるからです。サブスクリプションが頻繁に更新されていないように思えますか?

計算された場合、値が同じ場合でもそうなります。<code><div data-bind="text: Date()"></div> </をスローしてみることができますcode> をifセクションに追加して、日付が予想よりも頻繁に更新されているように見えるかどうかを確認します。

すべてが何度も再レンダリングされた場合、日付はほぼ同じになる可能性があります。値が true の場合、if バインディングは子要素のコピーを取得し、コピーをテンプレートとしてレンダリングしてそれに対してバインドするため、オーバーヘッドがわずかに大きくなります。visible は表示スタイルを設定するだけです。これで、初期値が false の可能性があり、非表示セクションに多くのマークアップ/バインディングがある場合、if バインディングによりパフォーマンスが向上します。if はそれらをレンダリングすることさえしませんが、visible はまだバインドしますが、非表示にするだけです。

if がある名前付きテンプレートも試すことができます。ifの内部で実行している場合foreach、KO は各 foreach アイテムの内部で子要素をテンプレートとして何度もコピーする必要があります。できます<div data-bind="template: { name: 'subItemTmpl', 'if': myFlag, data: subData"></div>

于 2012-10-02T02:13:31.027 に答える
1

コードを詳しく見ないと、何が問題なのかを理解するのは困難です。ifしかし、不要な再レンダリングを排除するためのバインディングの最適化を含む、Knockout の最新のリリース候補バージョンを使用することで、改善が見られる可能性があります。https://github.com/SteveSanderson/knockout/downloadsからダウンロードできます。

于 2012-10-01T19:45:18.157 に答える