I would like to share a little note on how to speed up the execution of $ digest () by replacing standard directives with equivalents that do not cause $ watch.
The point is that there are often a lot of elements on a page for which you need to band the data only once using data from models that do not change, for example:
<h1 ng-bind="l10n.main_title"></h1>
<a ng-href="/edit/{{user.id}}" ng-bind="user.name"></a>
These and other standard directives will kindly check if the value of the expression has changed for every $ digest. The situation can be rectified with a set of fairly simple custom directives, for example for text:
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>
The result is a minus one $ watch.
Of course, you don’t need to invent your own bike, there are two decent modules on GitHub:
The first ($ watch fighters) is quite simple, includes the following directives:
- set-title
- set-href
- set-text
- set-html
- set-class
- set-if
The second (Bindonce) is more interesting, because the developers thought that the data for the binding might not be available at the time of rendering the directive template (for example, they are loaded with an ajax request). It looks like this:
')
<div bindonce="User"> <h1 bo-text="User.name"></h1> </div>
For the parent
bindonce directive, a temporary $ watch is created, when the value of the variable passed to it becomes different from
undefined, nested bo- * directives are launched, and the temporary $ watch is deleted.
Bindonce module includes:
- bo-if
- bo-show
- bo-hide
- bo-text
- bo-html
- bo-href
- bo-src
- bo-class
- bo-alt
- bo-title
- bo-id
- bo-style
- bo-value
- bo-attr bo-attr-foo
More details can be found on
the repository page , there is a fairly extensive readme.
Lastly, I’ll give you the function I found
here . It
roughly calculates the total number of $ watch'ers on the page.
(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); })();
For the sake of interest, you can compare the amount of the before and the introduction of zero-watch guidelines.
I hope someone will come in handy. Thank.