One of the main benefits AngularJS provides is its two way databinding. It uses dirty checking to implement this, so whenever any value changes, then all the databound values are checked to see if they have also changed and updated accordingly. Fortunately the dirty checking is usually fast and it can be performed without any perceived lag from the end user (see this Stack Overflow post for a reference).

However, it’s still good to pay attention that a page does not contain thousands upon thousands of databound elements, though, because the user can start noticing a lag, especially from mobile devices. There is a Chrome extension called Batarang that can show you how many databound elements a page has, but it hasn’t been updated in over a year, and its recent reviews complain that the extension is broken for them. So I created a simple script that counts the number of databound elements on the page.

AngularJS keeps track of two way databound elements by adding a watcher function to the $$watchers array on the scope. So to find out how many dirty checks AngularJS performs on the page, we just need to count the number of watchers on every scope.

To do this, the first thing we need to do is get a reference to all the scopes on the page. This can be done by taking advantage of the fact that AngularJS adds the ng-scope class to every element that is associated with a scope. And then we can call angular.element(element).scope() on each element to retrieve a reference to the actual scope itself. Here is a code example showing how to get the scope from a single element on the page.

var elementsWithScope = document.querySelectorAll('.ng-scope');
var firstElementWithScope = elementsWithScope[0];
var scope = angular.element(firstElementWithScope).scope();

And then we can loop through each scope and count the number of watchers.

Here is what the final code snippet looks like:

countWatchers = function() {
  var watchers, elementsWithScope, scope, i, len;
  watchers = 0;
  elementsWithScope = document.querySelectorAll('.ng-scope');
  for (i = 0, len = elementsWithScope.length; i < len; i++) {
    scope = angular.element(elementsWithScope[i]).scope();
    if (scope.$$watchers != null) {
      watchers += scope.$$watchers.length; 
    } 
  } 
  return watchers;
};

And once you include this JavaScript in you AngularJS site, you can open up the browser console on any page and type countWatchers(), and it will return the number of watchers on the page.

Bookmarklet

When I shared this code snippet with my co-worker, Eric Guthmann, he mentioned that it could easily be made into a bookmarklet so that it can be used on any AngularJS site. And then there wouldn’t be the need to manually include a JavaScript file with the website itself. So with his help, I created the bookmarklet below.

You can save the bookmarklet below by dragging and dropping it on your bookmark bar.

AngularJS Watcher Count


Navigation