余分な$ウォッチャーを取り除く

標準のディレクティブを$ watchを呼び出さない同等のディレクティブに置き換えることで、$ digest()の実行を高速化する方法について簡単なメモを共有したいと思います。



ポイントは、多くの場合、変更されないモデルデータを使用して一度だけデータをバインドする必要がある要素がページ上にあることです。



<h1 ng-bind="l10n.main_title"></h1>
      
      





 <a ng-href="/edit/{{user.id}}" ng-bind="user.name"></a>
      
      





これらおよび他の標準ディレクティブは、式の値が$ダイジェストごとに変更されたかどうかを親切にチェックします。 この状況は、テキスト用などのかなり単純なカスタムディレクティブのセットによって修正できます。



 app.directive("staticText", function() { return { restrict: "A" link: function(scope, element, attrs) { element.text(scope.$eval(attrs.customText)); } }; })
      
      





 <h1 static-text="l10n.main_title"></h1>
      
      





結果はマイナス1ドルです。

もちろん、自転車を発明する必要はありません。GitHubには2つの価値のあるモジュールがあります。



最初の($ watch fighters)は非常に単純で、次のディレクティブが含まれています。



2番目(Bindonce)はより興味深いです。 開発者は、バインディング用のデータはディレクティブテンプレートのレンダリング時に使用できない可能性があると考えました(たとえば、ajaxリクエストでロードされます)。 次のようになります。



 <div bindonce="User"> <h1 bo-text="User.name"></h1> </div>
      
      





bindonceディレクティブの場合、一時$ウォッチが作成され、それに渡される変数の値が未定義と異なる場合、ネストされたbo- *ディレクティブが起動され、一時$ウォッチが削除されます。

Bindonceモジュールには以下が含まれます。



リポジトリページで詳細を読むことができます。かなり詳細なreadmeがあります。



最後に、 ここで見つけた機能を示します 。 1ページあたりの$ウォッチャーの総数を大まかに計算します。



 (function () { var root = $(document.getElementsByTagName('body')); var watchers = []; var f = function (element) { if (element.data().hasOwnProperty('$scope')) { angular.forEach(element.data().$scope.$$watchers, function (watcher) { watchers.push(watcher); }); } angular.forEach(element.children(), function (childElement) { f($(childElement)); }); }; f(root); console.log(watchers.length); })();
      
      





興味のために、ゼロウォッチディレクティブの量と実装フィールドを比較できます。

誰かが役に立つといいな。 ありがとう



All Articles