How to count total number of watches on a page?

I think the mentioned approaches are inaccurate since they count watchers in the same scope double. Here is my version of a bookmarklet:

https://gist.github.com/DTFagus/3966db108a578f2eb00d

It also shows some more details for analyzing watchers.


(You may need to change body to html or wherever you put your ng-app)

(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);
})();
  • Thanks to erilem for pointing out this answer was missing the $isolateScope searching and the watchers potentially being duplicated in his/her answer/comment.

  • Thanks to Ben2307 for pointing out that the 'body' may need to be changed.


Original

I did the same thing except I checked the data attribute of the HTML element rather than its class. I ran yours here:

http://fluid.ie/

And got 83. I ran mine and got 121.

(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);
})();

I also put this in mine:

for (var i = 0; i < watchers.length; i++) {
    for (var j = 0; j < watchers.length; j++) {
        if (i !== j && watchers[i] === watchers[j]) {
            console.log('here');
        }
    }
}

And nothing printed out, so I'm guessing that mine is better (in that it found more watches) - but I lack intimate angular knowledge to know for sure that mine isn't a proper subset of the solution set.

Tags:

Angularjs