Skip to content

Commit 9b425fc

Browse files
committed
Added method to count number of digest cycles
1 parent cb93917 commit 9b425fc

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ with given name.
6666
that surrounds given selector. Useful to find parts of the page with expensive watchers.
6767
* [ng-find-expensive-digest.js](ng-find-expensive-digest.js) builds upon ng-profile-local-digest.js to measure
6868
digest duration for several selectors and print sorted table starting with the slowest digest duration.
69+
* [ng-count-digest-cycles.js](ng-count-digest-cycles.js) - counts number of full digest cycles (from the root scope)
70+
that run when a scope method executes. Useful because sometimes you can get away with just a local digest
71+
cycle, rather than a full update. See [Local Angular scopes](http://glebbahmutov.com/blog/local-angular-scopes/).
6972

7073
All snippets, including mine are distributed under MIT license.
7174

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "code-snippets",
33
"main": "first-paint.js",
4-
"version": "0.2.0",
4+
"version": "0.3.0",
55
"homepage": "https://github.com/bahmutov/code-snippets",
66
"license": "MIT",
77
"ignore": [

ng-count-digest-cycles.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Adds a watch expression on the root scope that counts the number of times
3+
it was called. After method stops, restores the original method and
4+
prints number of times digest cycle was run.
5+
Method can return a promise.
6+
Typical use: see how many times the full digest cycle is triggered.
7+
8+
$scope.myMethod = function () ...
9+
where $scope could be determined from element 'my-selector'
10+
*/
11+
(function countDigestCycles() {
12+
var selector = 'button';
13+
var methodName = 'doSomething';
14+
var name = selector + ':' + methodName;
15+
16+
/* global angular */
17+
var el = angular.element(document.getElementById(selector));
18+
var scope = el.scope() || el.isolateScope();
19+
console.assert(scope, 'cannot find scope from ' + name);
20+
21+
var fn = scope[methodName];
22+
console.assert(typeof fn === 'function', 'missing ' + methodName);
23+
var $rootScope = el.injector().get('$rootScope');
24+
25+
var count = 0;
26+
$rootScope.$watch(function () {
27+
count += 1;
28+
});
29+
30+
var $q = el.injector().get('$q');
31+
32+
scope[methodName] = function () {
33+
34+
count = 0;
35+
36+
// method can return a value or a promise
37+
var returned = fn();
38+
$q.when(returned).finally(function finishedMethod() {
39+
scope.$$postDigest(function () {
40+
scope[methodName] = fn;
41+
console.log('restored', methodName);
42+
console.log('digest cycle ran', count, 'time(s) during', name);
43+
});
44+
});
45+
};
46+
console.log('wrapped', name, 'for measuring number of digest cycles');
47+
48+
}());

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "code-snippets",
33
"description": "Chrome DevTools code snippets ",
4-
"version": "0.2.0",
4+
"version": "0.3.0",
55
"author": "Gleb Bahmutov <gleb.bahmutov@gmail.com>",
66
"bugs": {
77
"url": "https://github.com/bahmutov/code-snippets/issues"

test/count-digest-cycles.html

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<script src="https://code.angularjs.org/1.3.15/angular.js"></script>
6+
<script>
7+
angular.module('MyApp', [])
8+
.controller('ctrl', function ($scope, $timeout, $rootScope) {
9+
$scope.doSomething = function doSomething() {
10+
console.log('doing something');
11+
12+
/*
13+
return $timeout(function () {
14+
console.log('finished $timeout');
15+
}, 50);*/
16+
};
17+
18+
/*
19+
$rootScope.$watch(function () {
20+
console.log('$rootScope.$watch executed');
21+
});
22+
*/
23+
});
24+
</script>
25+
</head>
26+
27+
<body ng-app="MyApp">
28+
<h1>Count digest cycles</h1>
29+
<div ng-controller="ctrl">
30+
<p>controller</p>
31+
<button id="button" ng-click="doSomething()">Do something</button>
32+
</div>
33+
</body>
34+
</html>

0 commit comments

Comments
 (0)