Count watchers


#1

Hello,

i want to make some performance optimizations on my shopping app.

Is there a easy way to count the used watchers on the scope in ionic?

I tried ng-stats but it seems not to work with ionic because there is no .ng-scope element and no $$watchers list.


#2

I’d like to know the answer to this too. I normally use this code (as bookmark) for angular apps, but it doesn’t seem to work with ionic.


#3

I just add the watchers count to my debug logging (when the app goes live, I switch debug logging off for production mode). The way I’ve done it is to enhance the built-in #log logger with a ‘loggingDecorator’ factory like this:

.factory('loggingDecorator', function (dateFilter) {
  var decorate = function(log) {

    log.log = enhanceLogging(log.log);
    log.info = enhanceLogging(log.info);
    log.warn = enhanceLogging(log.warn);
    log.debug = enhanceLogging(log.debug);
    log.error = enhanceLogging(log.error);

    log.getLogger = function(context) {
      return {
        log   : enhanceLogging(log.log, context),
        info  : enhanceLogging(log.info, context),
        warn  : enhanceLogging(log.warn, context),
        debug : enhanceLogging(log.debug, context, true),
        error : enhanceLogging(log.error, context)
      };
    };
  };

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

  function enhanceLogging(loggingFunc, context, debug) {
    return function () {
      var modifiedArguments = [].slice.call(arguments)

      var prefix = "";

      if (context) {
        prefix = '[' + context + ']';
      } else {
        prefix = dateFilter(new Date(), 'yyyy-MM-dd HH:mm:ss')
      }

      if (debug) {
        prefix += " {WATCHERS: " + getWatchers().length + "} ";
      }

      modifiedArguments[0] = prefix + " - " + modifiedArguments[0];

      loggingFunc.apply(null, modifiedArguments);
    };
  }

  return {
    decorate: decorate
  }
})

Then in my app.js (angular "run" function) I call it like this:
.run(function ($ionicPlatform, $state, $log, loggingDecorator) {

  loggingDecorator.decorate($log);

  // and so on ......
});

And (also in my app.js) I can switch off debug logging inside a .config function like this:
.config(function ($logProvider) {
  $logProvider.debugEnabled(false); // default is true
})