@shopgate/pwa-benchmark 7.30.0-alpha.6 → 7.30.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +201 -29
- package/keyFigure.js +181 -31
- package/package.json +1 -1
- package/profilers/redux.js +11 -1
package/index.js
CHANGED
|
@@ -1,49 +1,221 @@
|
|
|
1
|
-
|
|
1
|
+
import "core-js/modules/es.array.reduce.js";
|
|
2
|
+
import KeyFigure, { KEY_FIGURE_MODE_ADD, KEY_FIGURE_METHOD_TIME, KEY_FIGURE_METHOD_COUNT, KEY_FIGURE_METHOD_OBSERVER } from "./keyFigure";
|
|
3
|
+
const HEADLINE_STYLE = 'font-size: 24px; margin-top: 32px; margin-bottom: 12px;';
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* Benchmark controller.
|
|
3
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
class BenchmarkController {
|
|
9
|
+
/**
|
|
4
10
|
* Init
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
*/
|
|
12
|
+
constructor() {
|
|
13
|
+
/**
|
|
14
|
+
* Sorts measured actions descending.
|
|
15
|
+
* @param {Array} actions Measured actions.
|
|
16
|
+
* @param {Function} getA Getter to get left side.
|
|
17
|
+
* @param {Function} getB Getter to get right side.
|
|
18
|
+
* @returns {Array}
|
|
19
|
+
*/
|
|
20
|
+
this.sortMeasure = (actions, getA, getB) => actions.sort((a, b) => {
|
|
21
|
+
const measureA = getA(a);
|
|
22
|
+
const measureB = getB(b);
|
|
23
|
+
if (measureA < measureB) {
|
|
24
|
+
return -1;
|
|
25
|
+
}
|
|
26
|
+
if (measureA > measureB) {
|
|
27
|
+
return 1;
|
|
28
|
+
}
|
|
29
|
+
return 0;
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* Takes measure from all actions / components and adds it to a total.
|
|
33
|
+
* @param {Array} measure List of measures.
|
|
34
|
+
* @returns {Array}
|
|
35
|
+
*/
|
|
36
|
+
this.getTotals = measure => {
|
|
37
|
+
const result = [];
|
|
38
|
+
Object.keys(measure).forEach(action => Object.keys(measure[action]).forEach(component => {
|
|
39
|
+
const found = result.find(r => r.name === component);
|
|
40
|
+
if (found) {
|
|
41
|
+
found.render += measure[action][component].render;
|
|
42
|
+
found.renderTime += measure[action][component].renderTime;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
result.push({
|
|
46
|
+
name: component,
|
|
47
|
+
render: measure[action][component].render,
|
|
48
|
+
renderTime: measure[action][component].renderTime
|
|
49
|
+
});
|
|
50
|
+
}));
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
this.keyFigures = {};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
16
57
|
* Startsup the controller
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
58
|
+
*/
|
|
59
|
+
startup() {
|
|
60
|
+
// Redux key figures.
|
|
61
|
+
this.addKeyFigure('ActionCount', new KeyFigure(KEY_FIGURE_MODE_ADD, KEY_FIGURE_METHOD_COUNT));
|
|
62
|
+
this.addKeyFigure('ActionTime', new KeyFigure(KEY_FIGURE_MODE_ADD, KEY_FIGURE_METHOD_TIME));
|
|
63
|
+
this.addKeyFigure('ActionEvents', new KeyFigure(KEY_FIGURE_MODE_ADD, KEY_FIGURE_METHOD_OBSERVER));
|
|
64
|
+
this.addKeyFigure('GlobalEvents', new KeyFigure(KEY_FIGURE_MODE_ADD, KEY_FIGURE_METHOD_OBSERVER));
|
|
65
|
+
|
|
66
|
+
// Add global events.
|
|
67
|
+
this.getKeyFigure('GlobalEvents').startMeasure('global');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
20
71
|
* Adds a key figure.
|
|
21
72
|
* @param {string} name Name
|
|
22
73
|
* @param {KeyFigure} keyFigure KeyFigure
|
|
23
|
-
*/
|
|
74
|
+
*/
|
|
75
|
+
addKeyFigure(name, keyFigure) {
|
|
76
|
+
this.keyFigures[name] = keyFigure;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
24
80
|
* Gets a key figure.
|
|
25
81
|
* @param {string} name Name
|
|
26
82
|
* @param {KeyFigure} keyfigure KeyFigure
|
|
27
83
|
* @returns {Object}
|
|
28
|
-
*/
|
|
84
|
+
*/
|
|
85
|
+
getKeyFigure(name) {
|
|
86
|
+
return this.keyFigures[name];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
29
90
|
* Benchmark debug log;
|
|
30
|
-
*/
|
|
91
|
+
*/
|
|
92
|
+
debug() {
|
|
93
|
+
console.log('=========================');
|
|
94
|
+
console.log('Benchmark Debug Log');
|
|
95
|
+
console.log('=========================');
|
|
96
|
+
console.log(this.keyFigures);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
31
99
|
* Prints most called actions.
|
|
32
|
-
*/
|
|
33
|
-
|
|
100
|
+
*/
|
|
101
|
+
printMostCalledActions() {
|
|
102
|
+
// Most called actions.
|
|
103
|
+
const {
|
|
104
|
+
measure
|
|
105
|
+
} = this.getKeyFigure('ActionCount');
|
|
106
|
+
const actions = Object.keys(measure.inclusive);
|
|
107
|
+
const sortedAction = this.sortMeasure(actions, a => measure.inclusive[a], b => measure.inclusive[b]);
|
|
108
|
+
console.log('%cMost called actions', HEADLINE_STYLE);
|
|
109
|
+
console.table(sortedAction.map(action => ({
|
|
110
|
+
Action: action,
|
|
111
|
+
Count: measure.inclusive[action]
|
|
112
|
+
})).reverse().slice(0, 10));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
34
116
|
* Prints the highest execution time per action on average.
|
|
35
117
|
* @param {string} type "inclusive" or "exclusive"
|
|
36
|
-
*/
|
|
37
|
-
|
|
118
|
+
*/
|
|
119
|
+
printHighestAverageAction(type = 'inclusive') {
|
|
120
|
+
// Highest average execution time
|
|
121
|
+
const {
|
|
122
|
+
measure
|
|
123
|
+
} = this.getKeyFigure('ActionTime');
|
|
124
|
+
const {
|
|
125
|
+
measure: measureCount
|
|
126
|
+
} = this.getKeyFigure('ActionCount');
|
|
127
|
+
const actions = Object.keys(measure[type]);
|
|
128
|
+
const sortedAction = this.sortMeasure(actions, a => measure[type][a] / measureCount[type][a], b => measure[type][b] / measureCount[type][b]);
|
|
129
|
+
console.log(`%cHighest average execution time (${type})`, HEADLINE_STYLE);
|
|
130
|
+
console.table(sortedAction.map(action => ({
|
|
131
|
+
Action: action,
|
|
132
|
+
Time: measure[type][action] / measureCount[type][action]
|
|
133
|
+
})).reverse().slice(0, 10));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
38
137
|
* Prints most rendering actions.
|
|
39
|
-
*/
|
|
138
|
+
*/
|
|
139
|
+
printsActionsWithMostRenders() {
|
|
140
|
+
const measure = this.getKeyFigure('ActionEvents').measure.inclusive;
|
|
141
|
+
const actions = Object.keys(measure).map(action => Object.keys(measure[action]).reduce((acc, current) => ({
|
|
142
|
+
action,
|
|
143
|
+
render: measure[action][current].render + acc.render,
|
|
144
|
+
renderTime: measure[action][current].renderTime + acc.renderTime
|
|
145
|
+
}), {
|
|
146
|
+
action,
|
|
147
|
+
render: 0,
|
|
148
|
+
renderTime: 0
|
|
149
|
+
}));
|
|
150
|
+
const sortedAction = this.sortMeasure(actions, a => a.render, b => b.render);
|
|
151
|
+
console.log('%cAction that caused most renders', HEADLINE_STYLE);
|
|
152
|
+
console.table(sortedAction.map(action => ({
|
|
153
|
+
Action: action.action,
|
|
154
|
+
Renders: action.render,
|
|
155
|
+
SumRenderTime: action.renderTime,
|
|
156
|
+
AvgRenderTime: action.render > 0 ? action.renderTime / action.render : 0
|
|
157
|
+
})).reverse().slice(0, 10), ['Action', 'Renders', 'SumRenderTime', 'AvgRenderTime']);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
40
160
|
* Prints the most rendering components.
|
|
41
|
-
*/
|
|
161
|
+
*/
|
|
162
|
+
printsMostRenderedComponents() {
|
|
163
|
+
const measure = this.getKeyFigure('GlobalEvents').measure.inclusive;
|
|
164
|
+
const result = this.getTotals(measure);
|
|
165
|
+
const sortedAction = this.sortMeasure(result, a => a.render, b => b.render);
|
|
166
|
+
console.log('%cMost rendered Components', HEADLINE_STYLE);
|
|
167
|
+
console.table(sortedAction.map(action => ({
|
|
168
|
+
Component: action.name,
|
|
169
|
+
Renders: action.render,
|
|
170
|
+
SumRenderTime: action.renderTime,
|
|
171
|
+
AvgRenderTime: action.render > 0 ? action.renderTime / action.render : 0
|
|
172
|
+
})).reverse().slice(0, 10), ['Component', 'Renders', 'SumRenderTime', 'AvgRenderTime']);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
42
176
|
* Prints summary.
|
|
43
|
-
*/
|
|
177
|
+
*/
|
|
178
|
+
printTotals() {
|
|
179
|
+
const measure = this.getKeyFigure('GlobalEvents').measure.inclusive;
|
|
180
|
+
const result = this.getTotals(measure);
|
|
181
|
+
const sumRenders = result.reduce((current, acc) => current + acc.render, 0);
|
|
182
|
+
const sumRenderTime = result.reduce((current, acc) => current + acc.renderTime, 0);
|
|
183
|
+
const avgRenderTime = sumRenderTime / sumRenders;
|
|
184
|
+
console.log('%cRender total', HEADLINE_STYLE);
|
|
185
|
+
console.log(`%cRenders: ${sumRenders}; Execution Time: ${sumRenderTime}ms; Average Execution Time: ${avgRenderTime}ms`, 'font-size: 16px; margin-bottom: 12px;');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
44
189
|
* Pretty prints result.
|
|
45
|
-
*/
|
|
190
|
+
*/
|
|
191
|
+
print() {
|
|
192
|
+
const globalEvents = this.getKeyFigure('GlobalEvents');
|
|
193
|
+
if (globalEvents.started) {
|
|
194
|
+
this.getKeyFigure('GlobalEvents').stopMeasure('global');
|
|
195
|
+
this.getKeyFigure('GlobalEvents').startMeasure('global');
|
|
196
|
+
}
|
|
197
|
+
this.printMostCalledActions();
|
|
198
|
+
this.printHighestAverageAction();
|
|
199
|
+
this.printsActionsWithMostRenders();
|
|
200
|
+
this.printsMostRenderedComponents();
|
|
201
|
+
this.printTotals();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
46
205
|
* Starts benchmarking all key figures.
|
|
47
|
-
*/
|
|
206
|
+
*/
|
|
207
|
+
startAll() {
|
|
208
|
+
Object.keys(this.keyFigures).forEach(keyFigure => this.keyFigures[keyFigure].setStarted(true));
|
|
209
|
+
this.getKeyFigure('GlobalEvents').startMeasure('global');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
48
213
|
* Stops benchmarking all key figures.
|
|
49
|
-
*/
|
|
214
|
+
*/
|
|
215
|
+
stopAll() {
|
|
216
|
+
this.getKeyFigure('GlobalEvents').stopMeasure('global');
|
|
217
|
+
Object.keys(this.keyFigures).forEach(keyFigure => this.keyFigures[keyFigure].setStarted(false));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
window.benchmark = new BenchmarkController();
|
|
221
|
+
export default window.benchmark;
|
package/keyFigure.js
CHANGED
|
@@ -1,28 +1,100 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import "core-js/modules/es.string.replace.js";
|
|
2
|
+
export const KEY_FIGURE_MODE_ADD = 'add';
|
|
3
|
+
|
|
4
|
+
// Score is genereated by counting the occurence of each key.
|
|
5
|
+
export const KEY_FIGURE_METHOD_COUNT = 'count';
|
|
6
|
+
// Score is generated by measuring time between each key was started and stopped.
|
|
7
|
+
export const KEY_FIGURE_METHOD_TIME = 'time';
|
|
8
|
+
// Score is generated by collecting "performance events" during a start and stop. (chrome only)
|
|
9
|
+
export const KEY_FIGURE_METHOD_OBSERVER = 'observer';
|
|
10
|
+
|
|
11
|
+
/**
|
|
5
12
|
* Class
|
|
6
|
-
*/
|
|
13
|
+
*/
|
|
14
|
+
export default class KeyFigure {
|
|
15
|
+
/**
|
|
7
16
|
* Initializes the keyfigure and set it as started.
|
|
8
17
|
* @param {string} mode Append mode.
|
|
9
18
|
* @param {string} method Method.
|
|
10
|
-
*/
|
|
19
|
+
*/
|
|
20
|
+
constructor(mode, method) {
|
|
21
|
+
this.mode = mode;
|
|
22
|
+
this.method = method;
|
|
23
|
+
this.setStarted(true);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
11
27
|
* Toggles the status of the benchmark and also clears the result.
|
|
12
|
-
* @param {
|
|
13
|
-
*/
|
|
28
|
+
* @param {boolean} started Whether benchmark is running or not.
|
|
29
|
+
*/
|
|
30
|
+
setStarted(started) {
|
|
31
|
+
if (started) {
|
|
32
|
+
this.measure = {
|
|
33
|
+
exclusiveTimers: [],
|
|
34
|
+
timings: {},
|
|
35
|
+
observers: {},
|
|
36
|
+
inclusive: {},
|
|
37
|
+
exclusive: {}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
this.started = true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
14
44
|
* Starts measuring.
|
|
15
45
|
* @param {string} key Unique identifier for action.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
if(this.
|
|
19
|
-
|
|
20
|
-
|
|
46
|
+
*/
|
|
47
|
+
startMeasure(key) {
|
|
48
|
+
if (!this.started) return;
|
|
49
|
+
|
|
50
|
+
// Prepare storage for key if not existing yet.
|
|
51
|
+
if (typeof this.measure.inclusive[key] === 'undefined') {
|
|
52
|
+
this.measure.inclusive[key] = this.method !== KEY_FIGURE_METHOD_OBSERVER ? 0 : {};
|
|
53
|
+
this.measure.exclusive[key] = this.method !== KEY_FIGURE_METHOD_OBSERVER ? 0 : {};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Push the current start time into an array (allows to collect the action multiple times)
|
|
57
|
+
if (this.method === KEY_FIGURE_METHOD_TIME) {
|
|
58
|
+
this.measure.timings[key] = this.measure.timings[key] || [];
|
|
59
|
+
this.measure.timings[key].push({
|
|
60
|
+
start: performance.now(),
|
|
61
|
+
stop: null,
|
|
62
|
+
others: {}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Push the performance observer instance and start watching for events.
|
|
67
|
+
if (this.method === KEY_FIGURE_METHOD_OBSERVER) {
|
|
68
|
+
// Create observer and start observing.
|
|
69
|
+
const observer = {
|
|
70
|
+
instance: new PerformanceObserver(event => observer.stored.push(...event.getEntries())),
|
|
71
|
+
events: [],
|
|
72
|
+
stored: []
|
|
73
|
+
};
|
|
74
|
+
observer.instance.observe({
|
|
75
|
+
entryTypes: ['measure', 'paint', 'navigation', 'resource']
|
|
76
|
+
});
|
|
77
|
+
this.measure.observers[key] = this.measure.observers[key] || [];
|
|
78
|
+
this.measure.observers[key].push(observer);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
21
83
|
* Stops measuring.
|
|
22
84
|
* @param {string} key Unique key.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
if(this.
|
|
85
|
+
*/
|
|
86
|
+
stopMeasure(key) {
|
|
87
|
+
if (!this.started) return;
|
|
88
|
+
|
|
89
|
+
// For counting mode just increment the call count.
|
|
90
|
+
if (this.method === KEY_FIGURE_METHOD_COUNT) {
|
|
91
|
+
this.measure.inclusive[key] += 1;
|
|
92
|
+
this.measure.exclusive[key] += 1;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Evaluate performance events.
|
|
96
|
+
if (this.method === KEY_FIGURE_METHOD_OBSERVER) {
|
|
97
|
+
/*
|
|
26
98
|
* Collect all events from the observer.
|
|
27
99
|
*
|
|
28
100
|
* NOTE: Chrome behaves different in certain cases:
|
|
@@ -30,21 +102,99 @@ if(this.method===KEY_FIGURE_METHOD_OBSERVER){/*
|
|
|
30
102
|
* the event callback is called for each event.
|
|
31
103
|
* - The event callback is not executed at all but `takeRecords`
|
|
32
104
|
* will return all events.
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
105
|
+
*/
|
|
106
|
+
const {
|
|
107
|
+
instance,
|
|
108
|
+
stored
|
|
109
|
+
} = this.measure.observers[key].pop();
|
|
110
|
+
const records = instance.takeRecords();
|
|
111
|
+
const events = records.length === 0 ? stored : records;
|
|
112
|
+
instance.disconnect(); // Stops observing, free memory etc.
|
|
113
|
+
|
|
114
|
+
// We have to parse the event name to figure out what kind of action it was.
|
|
115
|
+
const renders = events.filter(event => event.entryType === 'measure').filter(event => event.name.endsWith('[update]')).map(event => ({
|
|
116
|
+
duration: event.duration,
|
|
117
|
+
componentName: event.name.replace('⚛', '').replace(/ /g, '').replace('[update]', '')
|
|
118
|
+
}));
|
|
119
|
+
const mounts = events.filter(event => event.entryType === 'measure').filter(event => event.name.endsWith('.componentDidMount')).map(event => ({
|
|
120
|
+
duration: event.duration,
|
|
121
|
+
componentName: event.name.replace('⚛', '').replace(/ /g, '').replace('.componentDidMount', '')
|
|
122
|
+
}));
|
|
123
|
+
|
|
124
|
+
// Process renders that happened for each component during the benchmark.
|
|
125
|
+
renders.forEach(({
|
|
126
|
+
componentName,
|
|
127
|
+
duration
|
|
128
|
+
}) => {
|
|
129
|
+
// For the first time component rendered we need to start at 1.
|
|
130
|
+
this.measure.inclusive[key][componentName] = this.measure.inclusive[key][componentName] || {
|
|
131
|
+
render: 0,
|
|
132
|
+
renderTime: 0,
|
|
133
|
+
mount: 0,
|
|
134
|
+
mountTime: 0
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// Increment total renders by 1.
|
|
138
|
+
const comp = this.measure.inclusive[key][componentName];
|
|
139
|
+
comp.render += 1;
|
|
140
|
+
comp.renderTime += duration;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Process mounts
|
|
144
|
+
mounts.forEach(({
|
|
145
|
+
componentName,
|
|
146
|
+
duration
|
|
147
|
+
}) => {
|
|
148
|
+
// For the first time component mounted we need to start at 1.
|
|
149
|
+
this.measure.inclusive[key][componentName] = this.measure.inclusive[key][componentName] || {
|
|
150
|
+
render: 0,
|
|
151
|
+
renderTime: 0,
|
|
152
|
+
mount: 0,
|
|
153
|
+
mountTime: 0
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// Increment total mounts by 1.
|
|
157
|
+
const comp = this.measure.inclusive[key][componentName];
|
|
158
|
+
comp.mount += 1;
|
|
159
|
+
comp.mountTime += duration;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// For timing mode we diff start with end time and summarize the timing.
|
|
164
|
+
if (this.method === KEY_FIGURE_METHOD_TIME) {
|
|
165
|
+
// Add inclusive timer.
|
|
166
|
+
const timing = this.measure.timings[key].pop();
|
|
167
|
+
const time = performance.now() - timing.start;
|
|
168
|
+
|
|
169
|
+
// Add exclusive timer.
|
|
170
|
+
this.measure.exclusiveTimers.push({
|
|
171
|
+
key,
|
|
172
|
+
time
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Calculate measure.
|
|
176
|
+
const currentMeasure = {
|
|
177
|
+
inclusive: time,
|
|
178
|
+
exclusive: time
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
46
182
|
* Calculates exclusive timings by removing other executions that
|
|
47
183
|
* were running at the same time.
|
|
48
184
|
* https://stackoverflow.com/a/17902682
|
|
49
|
-
*/
|
|
50
|
-
if(this.measure.exclusiveTimers.length
|
|
185
|
+
*/
|
|
186
|
+
if (this.measure.exclusiveTimers.length >= 2) {
|
|
187
|
+
const [first, ...remaining] = this.measure.exclusiveTimers;
|
|
188
|
+
this.measure.exclusiveTimers = remaining;
|
|
189
|
+
currentMeasure.exclusive -= first.time;
|
|
190
|
+
|
|
191
|
+
// Reset if callstack reached last call.
|
|
192
|
+
if (this.measure.exclusiveTimers.length === 1) {
|
|
193
|
+
this.measure.exclusiveTimers = [];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
this.measure.inclusive[key] += currentMeasure.inclusive;
|
|
197
|
+
this.measure.exclusive[key] += currentMeasure.exclusive;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
package/package.json
CHANGED
package/profilers/redux.js
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
-
import Benchmark from'..';
|
|
1
|
+
import Benchmark from '..';
|
|
2
|
+
export default () => next => action => {
|
|
3
|
+
Benchmark.getKeyFigure('ActionCount').startMeasure(action.type);
|
|
4
|
+
Benchmark.getKeyFigure('ActionTime').startMeasure(action.type);
|
|
5
|
+
Benchmark.getKeyFigure('ActionEvents').startMeasure(action.type);
|
|
6
|
+
const result = next(action);
|
|
7
|
+
Benchmark.getKeyFigure('ActionEvents').stopMeasure(action.type);
|
|
8
|
+
Benchmark.getKeyFigure('ActionTime').stopMeasure(action.type);
|
|
9
|
+
Benchmark.getKeyFigure('ActionCount').stopMeasure(action.type);
|
|
10
|
+
return result;
|
|
11
|
+
};
|