Hackviking He killed Chuck Norris, he ruled dancing so he took up a new hobby…

29Feb/160

AngularJS: Directive for checking # of watchers in scope

Performance is key in web development. Many developers forget this since there machines usually are more powerful then the average user machine. This is really important to take into account when building client side applications. In AngularJS the ng-repeat can be a source of bad performance, it's super convenient to use but can create both digest loops and performance issues. Most of the time the performance can improve if you cut back on the two-way bindings. Every two-way binding creates a watcher that fires if something is changed, since Angular dosen't know what changed it checks every watcher in the current scope of the change.

So if you are only displaying data with ng-repeat without any editing function there is no reason to use a two-way binding like {{whateverdata}}, instead you should use a one way binding like {{::whateverdata}}. This approach will save the number of watchers. When I develop in Angular I use a simple directive to double check my scopes for the number of watchers created. It gives me quick access to the figure and I can see if changes to the application affects the number of watchers.

.directive('scopewatchers', function($timeout) {
  return {
    restrict: 'AE',
    replace: 'true',
    template: '<h2 ng-click="wcount()"># of watchers (click to update):{{watchers || "0"}}</h2>',
    controller: function($scope, $element) {
      $scope.wcount = function() {
        $timeout(function() {
          $scope.watchers = $scope.watchersContainedIn($scope);
        });
      };

      $scope.watchersContainedIn = function(scope) {
        var watchers = (scope.$$watchers) ? scope.$$watchers.length : 0;
        var child = scope.$$childHead;
        while (child) {
          watchers += (child.$$watchers) ? child.$$watchers.length : 0;
          child = child.$$nextSibling;
        }
        return watchers;
      };
    }
  };
})

Then I can easaly pop it into any scoop I want to check the number of watchers currently active in that scope.

<scopewatchers></scopewatchers>

I put together a Plunker demo of this built on the Digest Loop Demo I did a while back. With the amount of data in this demo it doesn't really do any difference if I have 500+ watchers or 2 watchers but the principal is the same. For larger datasets it can be a huge difference when ng-repeat inserts new items to the DOM or changes order of the items.

https://plnkr.co/edit/SlBYfp?p=info

Comments (0) Trackbacks (3)

    Leave a Reply