user3554664
user3554664

Reputation: 349

How to count Angular Watchers on Page?

How do I accurately count the number of watchers on a page?

I found a few different articles on how to do it, but they all give me different counts, so I'm struggling to find which is the correct way.

There is a StackOverflow here with the following code:

(function () { 
var root = angular.element(document.getElementsByTagName('body'));

var watchers = [];

var f = function (element) {
    angular.forEach(['$scope', '$isolateScope'], function (scopeProperty) { 
        if (element.data() && element.data().hasOwnProperty(scopeProperty)) {
            angular.forEach(element.data()[scopeProperty].$$watchers, function (watcher) {
                watchers.push(watcher);
            });
        }
    });

    angular.forEach(element.children(), function (childElement) {
        f(angular.element(childElement));
    });
};

f(root);

// Remove duplicate watchers
var watchersWithoutDuplicates = [];
angular.forEach(watchers, function(item) {
    if(watchersWithoutDuplicates.indexOf(item) < 0) {
         watchersWithoutDuplicates.push(item);
    }
});

console.log(watchersWithoutDuplicates.length);
})();

When I test it on the Angularjs.org homepage, it gives me 132 watchers.

I then found a Medium post here, with the following code:

function getWatchers(root) {
  root = angular.element(root || document.documentElement);
  var watcherCount = 0;

  function getElemWatchers(element) {
    var isolateWatchers = getWatchersFromScope(element.data().$isolateScope);
    var scopeWatchers = getWatchersFromScope(element.data().$scope);
    var watchers = scopeWatchers.concat(isolateWatchers);
    angular.forEach(element.children(), function (childElement) {
      watchers = watchers.concat(getElemWatchers(angular.element(childElement)));
    });
    return watchers;
  }

  function getWatchersFromScope(scope) {
    if (scope) {
      return scope.$$watchers || [];
    } else {
      return [];
    }
  }

  return getElemWatchers(root);
}
getWatchers().length

Testing this on Angularjs.org homepage returns 152 watchers.

Using simply angular.element('body').scope().$$watchersCount returns 80.

I understand that the SO code removes duplicates, is it removing duplicates that are watching the same expression (so there will only be one watcher listed for an expression like !visible), or it's removing duplicate watcher objects?

Update:

I realize the discrepancy is from duplicates. But, do duplicate watchers affect performance?

Upvotes: 2

Views: 1793

Answers (1)

rahul rathore
rahul rathore

Reputation: 379

This script will help you identify how many watchers are there on your page

just paste the below script on your browser's console and it will tell you the watcher count on your page

 function getWatchers(root) {
  root = angular.element(root || document.documentElement);
  var watcherCount = 0;

  function getElemWatchers(element) {
    var isolateWatchers = getWatchersFromScope(element.data().$isolateScope);
    var scopeWatchers = getWatchersFromScope(element.data().$scope);
    var watchers = scopeWatchers.concat(isolateWatchers);
    angular.forEach(element.children(), function (childElement) {
      watchers = watchers.concat(getElemWatchers(angular.element(childElement)));
    });
    return watchers;
  }

  function getWatchersFromScope(scope) {
    if (scope) {
      return scope.$$watchers || [];
    } else {
      return [];
    }
  }

  return getElemWatchers(root);
}
getWatchers().length

Upvotes: 1

Related Questions