Skip to content

Commit a353ed8

Browse files
tboschjeffbcross
authored andcommitted
refactor(perf): migration event delegation benchmark to benchpress
1 parent bf0e837 commit a353ed8

File tree

8 files changed

+206
-322
lines changed

8 files changed

+206
-322
lines changed

benchmarks/event-delegation-bp/app.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
var app = angular.module('eventDelegationBenchmark', []);
2+
3+
app.directive('noopDir', function() {
4+
return {
5+
compile: function($element, $attrs) {
6+
return function($scope, $element) {
7+
return 1;
8+
}
9+
}
10+
};
11+
});
12+
13+
app.directive('nativeClick', ['$parse', function($parse) {
14+
return {
15+
compile: function($element, $attrs) {
16+
var expr = $parse($attrs.tstEvent);
17+
return function($scope, $element) {
18+
$element[0].addEventListener('click', function() {
19+
console.log('clicked');
20+
}, false);
21+
}
22+
}
23+
};
24+
}]);
25+
26+
app.directive('dlgtClick', function() {
27+
return {
28+
compile: function($element, $attrs) {
29+
var evt = $attrs.dlgtClick;
30+
// We don't setup the global event listeners as the costs are small and one time only...
31+
}
32+
};
33+
});
34+
35+
app.controller('DataController', function($rootScope) {
36+
this.ngRepeatCount = 1000;
37+
this.rows = [];
38+
var self = this;
39+
40+
benchmarkSteps.push({
41+
name: '$apply',
42+
fn: function() {
43+
var oldRows = self.rows;
44+
$rootScope.$apply(function() {
45+
self.rows = [];
46+
});
47+
self.rows = oldRows;
48+
if (self.rows.length !== self.ngRepeatCount) {
49+
self.rows = [];
50+
for (var i=0; i<self.ngRepeatCount; i++) {
51+
self.rows.push('row'+i);
52+
}
53+
}
54+
$rootScope.$apply();
55+
}
56+
});
57+
});
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = function(config) {
2+
config.set({
3+
scripts: [{
4+
id: 'angular',
5+
src: '/build/angular.js'
6+
},{
7+
src: 'app.js',
8+
}]
9+
});
10+
};
+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<div ng-app="eventDelegationBenchmark">
2+
<div ng-controller="DataController as ctrl">
3+
<div class="container-fluid">
4+
5+
<p>
6+
Impact of event delegation.
7+
</p>
8+
9+
<p>
10+
<label>
11+
Number of ngRepeats:
12+
<input type="number" ng-model="ctrl.ngRepeatCount">
13+
</label>
14+
</p>
15+
16+
<p>
17+
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngClick">ngClick</label></div>
18+
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngClickNoJqLite">ngClick without jqLite</label></div>
19+
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngShow">baseline: ng-show</label></div>
20+
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="textInterpolation">baseline: text interpolation</label></div>
21+
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="dlgtClick">delegate event directive (only compile)</label></div>
22+
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="noopDir">baseline: noop directive (compile and link)</label></div>
23+
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="noop">baseline: no directive</label></div>
24+
</p>
25+
26+
<p>
27+
How to read the results:
28+
<ul>
29+
<li>The benchmark measures how long it takes to instantiate a given number of directives</li>
30+
<li>ngClick is compared against ngShow and text interpolation as baseline. The results show
31+
how expensive ngClick is compared to other very simple directives that touch the DOM.
32+
</li>
33+
<li>To measure the impact of jqLite.on vs element.addEventListener there is also a benchmark
34+
that as a modified version of ngClick that uses element.addEventListener.
35+
</li>
36+
<li>The delegate event directive is compared against a noop directive with a compile and link function and the case with no directives.
37+
The result shows how expensive it is to add a link function to a directive, as the delegate event directive has none.
38+
</li>
39+
</ul>
40+
</p>
41+
42+
<p>
43+
Results as of 7/31/2014:
44+
<ul>
45+
<li>ngClick is very close to ngShow and text interpolation, especially when looking at a version of ngClick that does not use jqLite.on but element.addEventListener instead.</li>
46+
<li>A delegate event directive that has no link function has the same speed as a directive with link function. I.e. ngClick is slower compared to the delegate event directive only because ngClick touches
47+
the DOM for every element</li>
48+
<li>A delegate event directive could be about 50% faster than ngClick. However, the overall performance
49+
benefit depends on how many (and which) other directives are used on the same element
50+
and what other things are part of the measures use case.
51+
E.g. rows of a table with ngRepeat that use ngClick will probably also contain text interpolation.
52+
</li>
53+
</ul>
54+
</p>
55+
56+
Debug output:
57+
<ng-switch on="benchmarkType">
58+
<div ng-switch-when="ngClick">
59+
<div>
60+
<span ng-repeat="row in ctrl.rows">
61+
<span ng-click="a()">1</span>
62+
<span ng-click="a()">1</span>
63+
<span ng-click="a()">1</span>
64+
<span ng-click="a()">1</span>
65+
</span>
66+
</div>
67+
</div>
68+
<div ng-switch-when="ngClickNoJqLite">
69+
<div>
70+
<span ng-repeat="row in ctrl.rows">
71+
<span native-click="a()">1</span>
72+
<span native-click="a()">1</span>
73+
<span native-click="a()">1</span>
74+
<span native-click="a()">1</span>
75+
<span native-click="a()">1</span>
76+
</span>
77+
</div>
78+
</div>
79+
<div ng-switch-when="ngShow">
80+
<div>
81+
<span ng-repeat="row in ctrl.rows">
82+
<span ng-show="true">1</span>
83+
<span ng-show="true">1</span>
84+
<span ng-show="true">1</span>
85+
<span ng-show="true">1</span>
86+
<span ng-show="true">1</span>
87+
</span>
88+
</div>
89+
</div>
90+
<div ng-switch-when="textInterpolation">
91+
<div>
92+
<span ng-repeat="row in ctrl.rows">
93+
<span>{{row}}</span>
94+
<span>{{row}}</span>
95+
<span>{{row}}</span>
96+
<span>{{row}}</span>
97+
<span>{{row}}</span>
98+
</span>
99+
</div>
100+
</div>
101+
<div ng-switch-when="dlgtClick">
102+
<div>
103+
<span ng-repeat="row in ctrl.rows">
104+
<span dlgt-click="a()">1</span>
105+
<span dlgt-click="a()">1</span>
106+
<span dlgt-click="a()">1</span>
107+
<span dlgt-click="a()">1</span>
108+
<span dlgt-click="a()">1</span>
109+
</span>
110+
</div>
111+
</div>
112+
<div ng-switch-when="noopDir">
113+
<div>
114+
<span ng-repeat="row in ctrl.rows">
115+
<span noop-dir>1</span>
116+
<span noop-dir>1</span>
117+
<span noop-dir>1</span>
118+
<span noop-dir>1</span>
119+
<span noop-dir>1</span>
120+
</span>
121+
</div>
122+
</div>
123+
<div ng-switch-when="noop">
124+
<div>
125+
<span ng-repeat="row in ctrl.rows">
126+
<span>1</span>
127+
<span>1</span>
128+
<span>1</span>
129+
<span>1</span>
130+
<span>1</span>
131+
</span>
132+
</div>
133+
</div>
134+
135+
</ng-switch>
136+
137+
</div>
138+
</div>
139+
</div>

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
"node-html-encoder": "0.0.2",
5555
"sorted-object": "^1.0.0",
5656
"qq": "^0.3.5",
57-
"benchmark": "1.x.x",
5857
"angular-benchpress": "0.x.x"
5958
},
6059
"licenses": [

perf/apps/event-delegation/app.js

-121
This file was deleted.

0 commit comments

Comments
 (0)