Moved calculation of self duration to the backend/renderer
This enables self duration to be computed accurately despite component filters
Brian Vaughn committed
May 13, 2019 at 10:13 UTC
cf99c3ee6c63749c0f2453ec325622c03558a2f0
9 files changed
+342
-115
src/__tests__/__snapshots__/profiling-test.js.snap
+152
-27
@@ -12,6 +12,13 @@ Object {
12
"commitIndex": 0,
13
"interactions": Array [],
14
"rootID": 1,
15
+ "selfDurations": Map {
16
+ 1 => 0,
17
+ 2 => 10,
18
+ 3 => 0,
19
+ 4 => 1,
20
+ 5 => 1,
21
+ },
22
}
23
`;
24
@@ -27,6 +34,13 @@ Object {
34
"commitIndex": 1,
35
"interactions": Array [],
36
"rootID": 1,
37
+ "selfDurations": Map {
38
+ 3 => 0,
39
+ 4 => 1,
40
+ 6 => 2,
41
+ 2 => 10,
42
+ 1 => 0,
43
+ },
44
}
45
`;
46
@@ -40,6 +54,11 @@ Object {
54
"commitIndex": 2,
55
"interactions": Array [],
56
"rootID": 1,
57
+ "selfDurations": Map {
58
+ 3 => 0,
59
+ 2 => 10,
60
+ 1 => 0,
61
+ },
62
}
63
`;
64
@@ -52,6 +71,10 @@ Object {
71
"commitIndex": 3,
72
"interactions": Array [],
73
"rootID": 1,
74
+ "selfDurations": Map {
75
+ 2 => 10,
76
+ 1 => 0,
77
+ },
78
}
79
`;
80
@@ -59,60 +82,75 @@ exports[`profiling CommitDetails should be collected for each commit: exported d
82
Object {
83
"commitDetails": Array [
84
Object {
62
- "actualDurations": Array [
85
+ "commitIndex": 0,
86
+ "durations": Array [
87
1,
88
12,
89
+ 0,
90
2,
91
12,
92
+ 10,
93
3,
94
0,
95
+ 0,
96
4,
97
1,
98
+ 1,
99
5,
100
1,
101
+ 1,
102
],
74
- "commitIndex": 0,
103
"interactions": Array [],
104
"rootID": 1,
105
},
106
Object {
79
- "actualDurations": Array [
107
+ "commitIndex": 1,
108
+ "durations": Array [
109
3,
110
0,
111
+ 0,
112
4,
113
1,
114
+ 1,
115
6,
116
2,
117
2,
118
+ 2,
119
13,
120
+ 10,
121
1,
122
13,
123
+ 0,
124
],
91
- "commitIndex": 1,
125
"interactions": Array [],
126
"rootID": 1,
127
},
128
Object {
96
- "actualDurations": Array [
129
+ "commitIndex": 2,
130
+ "durations": Array [
131
3,
132
0,
133
+ 0,
134
2,
135
10,
136
+ 10,
137
1,
138
10,
139
+ 0,
140
],
104
- "commitIndex": 2,
141
"interactions": Array [],
142
"rootID": 1,
143
},
144
Object {
109
- "actualDurations": Array [
145
+ "commitIndex": 3,
146
+ "durations": Array [
147
2,
148
10,
149
+ 10,
150
1,
151
10,
152
+ 0,
153
],
115
- "commitIndex": 3,
154
"interactions": Array [],
155
"rootID": 1,
156
},
@@ -295,15 +333,71 @@ Object {
333
}
334
`;
335
336
+exports[`profiling CommitDetails should calculate a self duration based on actual children (not filtered children): CommitDetails with filtered self durations 1`] = `
337
+Object {
338
+ "actualDurations": Map {
339
+ 1 => 16,
340
+ 2 => 16,
341
+ 3 => 1,
342
+ 5 => 1,
343
+ },
344
+ "commitIndex": 0,
345
+ "interactions": Array [],
346
+ "rootID": 1,
347
+ "selfDurations": Map {
348
+ 1 => 0,
349
+ 2 => 10,
350
+ 3 => 1,
351
+ 5 => 1,
352
+ },
353
+}
354
+`;
355
+
356
+exports[`profiling CommitDetails should calculate self duration correctly for suspended views: CommitDetails with filtered self durations 1`] = `
357
+Object {
358
+ "actualDurations": Map {
359
+ 1 => 15,
360
+ 2 => 15,
361
+ 3 => 5,
362
+ 4 => 2,
363
+ },
364
+ "commitIndex": 0,
365
+ "interactions": Array [],
366
+ "rootID": 1,
367
+ "selfDurations": Map {
368
+ 1 => 0,
369
+ 2 => 10,
370
+ 3 => 3,
371
+ 4 => 2,
372
+ },
373
+}
374
+`;
375
+
376
+exports[`profiling CommitDetails should calculate self duration correctly for suspended views: CommitDetails with filtered self durations 2`] = `
377
+Object {
378
+ "actualDurations": Map {
379
+ 5 => 3,
380
+ 3 => 3,
381
+ },
382
+ "commitIndex": 1,
383
+ "interactions": Array [],
384
+ "rootID": 1,
385
+ "selfDurations": Map {
386
+ 5 => 3,
387
+ 3 => 0,
388
+ },
389
+}
390
+`;
391
+
392
exports[`profiling FiberCommits should be collected for each rendered fiber: FiberCommits: element 2 1`] = `
393
Object {
394
"commitDurations": Array [
395
0,
302
- 11,
396
+ 10,
397
1,
304
- 11,
398
+ 10,
399
2,
306
- 13,
400
+ 10,
401
],
402
"fiberID": 2,
403
"rootID": 1,
@@ -364,49 +458,62 @@ exports[`profiling FiberCommits should be collected for each rendered fiber: exp
458
Object {
459
"commitDetails": Array [
460
Object {
367
- "actualDurations": Array [
461
+ "commitIndex": 0,
462
+ "durations": Array [
463
1,
464
11,
465
+ 0,
466
2,
467
11,
468
+ 10,
469
3,
470
0,
471
+ 0,
472
4,
473
1,
474
+ 1,
475
],
377
- "commitIndex": 0,
476
"interactions": Array [],
477
"rootID": 1,
478
},
479
Object {
382
- "actualDurations": Array [
480
+ "commitIndex": 1,
481
+ "durations": Array [
482
3,
483
0,
484
+ 0,
485
5,
486
1,
487
+ 1,
488
2,
489
11,
490
+ 10,
491
1,
492
11,
493
+ 0,
494
],
392
- "commitIndex": 1,
495
"interactions": Array [],
496
"rootID": 1,
497
},
498
Object {
397
- "actualDurations": Array [
499
+ "commitIndex": 2,
500
+ "durations": Array [
501
3,
502
0,
503
+ 0,
504
5,
505
1,
506
+ 1,
507
6,
508
2,
509
2,
510
+ 2,
511
13,
512
+ 10,
513
1,
514
13,
515
+ 0,
516
],
409
- "commitIndex": 2,
517
"interactions": Array [],
518
"rootID": 1,
519
},
@@ -609,17 +716,21 @@ exports[`profiling Interactions should be collected for every traced interaction
716
Object {
717
"commitDetails": Array [
718
Object {
612
- "actualDurations": Array [
719
+ "commitIndex": 0,
720
+ "durations": Array [
721
1,
722
11,
723
+ 0,
724
2,
725
11,
726
+ 10,
727
3,
728
0,
729
+ 0,
730
4,
731
1,
732
+ 1,
733
],
622
- "commitIndex": 0,
734
"interactions": Array [
735
Object {
736
"__count": 1,
@@ -631,17 +742,21 @@ Object {
742
"rootID": 1,
743
},
744
Object {
634
- "actualDurations": Array [
745
+ "commitIndex": 1,
746
+ "durations": Array [
747
3,
748
0,
749
+ 0,
750
5,
751
1,
752
+ 1,
753
2,
754
11,
755
+ 10,
756
1,
757
11,
758
+ 0,
759
],
644
- "commitIndex": 1,
760
"interactions": Array [
761
Object {
762
"__count": 0,
@@ -833,43 +948,53 @@ exports[`profiling ProfilingSummary should be collected for each commit: exporte
948
Object {
949
"commitDetails": Array [
950
Object {
836
- "actualDurations": Array [
951
+ "commitIndex": 0,
952
+ "durations": Array [
953
3,
954
0,
955
+ 0,
956
4,
957
1,
958
+ 1,
959
6,
960
2,
961
2,
962
+ 2,
963
13,
964
+ 10,
965
1,
966
13,
967
+ 0,
968
],
848
- "commitIndex": 0,
969
"interactions": Array [],
970
"rootID": 1,
971
},
972
Object {
853
- "actualDurations": Array [
973
+ "commitIndex": 1,
974
+ "durations": Array [
975
3,
976
0,
977
+ 0,
978
2,
979
10,
980
+ 10,
981
1,
982
10,
983
+ 0,
984
],
861
- "commitIndex": 1,
985
"interactions": Array [],
986
"rootID": 1,
987
},
988
Object {
866
- "actualDurations": Array [
989
+ "commitIndex": 2,
990
+ "durations": Array [
991
2,
992
10,
993
+ 10,
994
1,
995
10,
996
+ 0,
997
],
872
- "commitIndex": 2,
998
"interactions": Array [],
999
"rootID": 1,
1000
},
src/__tests__/profiling-test.js
+135
@@ -253,6 +253,141 @@ describe('profiling', () => {
253
254
done();
255
});
256
+
257
+ it('should calculate a self duration based on actual children (not filtered children)', async done => {
258
+ store.componentFilters = [utils.createDisplayNameFilter('^Parent$')];
259
+
260
+ const Grandparent = () => {
261
+ Scheduler.advanceTime(10);
262
+ return (
263
+ <React.Fragment>
264
+ <Parent key="one" />
265
+ <Parent key="two" />
266
+ </React.Fragment>
267
+ );
268
+ };
269
+ const Parent = () => {
270
+ Scheduler.advanceTime(2);
271
+ return <Child />;
272
+ };
273
+ const Child = () => {
274
+ Scheduler.advanceTime(1);
275
+ return null;
276
+ };
277
+
278
+ utils.act(() => store.startProfiling());
279
+ utils.act(() =>
280
+ ReactDOM.render(<Grandparent />, document.createElement('div'))
281
+ );
282
+ utils.act(() => store.stopProfiling());
283
+
284
+ let commitDetails = null;
285
+
286
+ function Suspender({ commitIndex, rendererID, rootID }) {
287
+ commitDetails = store.profilingCache.CommitDetails.read({
288
+ commitIndex,
289
+ rendererID,
290
+ rootID,
291
+ });
292
+ expect(commitDetails).toMatchSnapshot(
293
+ `CommitDetails with filtered self durations`
294
+ );
295
+ return null;
296
+ }
297
+
298
+ const rendererID = utils.getRendererID();
299
+ const rootID = store.roots[0];
300
+
301
+ await utils.actAsync(() => {
302
+ TestRenderer.create(
303
+ <React.Suspense fallback={null}>
304
+ <Suspender
305
+ commitIndex={0}
306
+ rendererID={rendererID}
307
+ rootID={rootID}
308
+ />
309
+ </React.Suspense>
310
+ );
311
+ });
312
+
313
+ expect(commitDetails).not.toBeNull();
314
+
315
+ done();
316
+ });
317
+
318
+ it('should calculate self duration correctly for suspended views', async done => {
319
+ let data;
320
+ const getData = () => {
321
+ if (data) {
322
+ return data;
323
+ } else {
324
+ throw new Promise(resolve => {
325
+ data = 'abc';
326
+ resolve(data);
327
+ });
328
+ }
329
+ };
330
+
331
+ const Parent = () => {
332
+ Scheduler.advanceTime(10);
333
+ return (
334
+ <React.Suspense fallback={<Fallback />}>
335
+ <Async />
336
+ </React.Suspense>
337
+ );
338
+ };
339
+ const Fallback = () => {
340
+ Scheduler.advanceTime(2);
341
+ return 'Fallback...';
342
+ };
343
+ const Async = () => {
344
+ Scheduler.advanceTime(3);
345
+ const data = getData();
346
+ return data;
347
+ };
348
+
349
+ utils.act(() => store.startProfiling());
350
+ await utils.actAsync(() =>
351
+ ReactDOM.render(<Parent />, document.createElement('div'))
352
+ );
353
+ utils.act(() => store.stopProfiling());
354
+
355
+ const allCommitDetails = [];
356
+
357
+ function Suspender({ commitIndex, rendererID, rootID }) {
358
+ const commitDetails = store.profilingCache.CommitDetails.read({
359
+ commitIndex,
360
+ rendererID,
361
+ rootID,
362
+ });
363
+ allCommitDetails.push(commitDetails);
364
+ expect(commitDetails).toMatchSnapshot(
365
+ `CommitDetails with filtered self durations`
366
+ );
367
+ return null;
368
+ }
369
+
370
+ const rendererID = utils.getRendererID();
371
+ const rootID = store.roots[0];
372
+
373
+ for (let commitIndex = 0; commitIndex < 2; commitIndex++) {
374
+ await utils.actAsync(() => {
375
+ TestRenderer.create(
376
+ <React.Suspense fallback={null}>
377
+ <Suspender
378
+ commitIndex={commitIndex}
379
+ rendererID={rendererID}
380
+ rootID={rootID}
381
+ />
382
+ </React.Suspense>
383
+ );
384
+ });
385
+ }
386
+
387
+ expect(allCommitDetails).toHaveLength(2);
388
+
389
+ done();
390
+ });
391
});
392
393
describe('FiberCommits', () => {
src/backend/renderer.js
+33
-41
@@ -787,13 +787,8 @@ export function attach(
787
const isRoot = fiber.tag === HostRoot;
788
const id = getFiberID(getPrimaryFiber(fiber));
789
790
- const isProfilingSupported = fiber.hasOwnProperty('treeBaseDuration');
791
- if (isProfilingSupported) {
792
- idToRootMap.set(id, currentRootID);
793
- idToTreeBaseDurationMap.set(id, fiber.treeBaseDuration || 0);
794
- }
795
-
790
const hasOwnerMetadata = fiber.hasOwnProperty('_debugOwner');
791
+ const isProfilingSupported = fiber.hasOwnProperty('treeBaseDuration');
792
793
if (isRoot) {
794
pushOperation(TREE_OPERATION_ADD);
@@ -824,26 +819,10 @@ export function attach(
819
pushOperation(keyStringID);
820
}
821
827
- if (isProfiling) {
828
- // Tree base duration updates are included in the operations typed array.
829
- // So we have to convert them from milliseconds to microseconds so we can send them as ints.
830
- const treeBaseDuration = Math.floor((fiber.treeBaseDuration || 0) * 1000);
822
+ if (isProfilingSupported) {
823
+ idToRootMap.set(id, currentRootID);
824
832
- pushOperation(TREE_OPERATION_UPDATE_TREE_BASE_DURATION);
833
- pushOperation(id);
834
- pushOperation(treeBaseDuration);
835
-
836
- const { actualDuration } = fiber;
837
- if (actualDuration != null) {
838
- // If profiling is active, store durations for elements that were rendered during the commit.
839
- // We should do this for all fibers on mount, regardless of their actual durations.
840
- const metadata = ((currentCommitProfilingMetadata: any): CommitProfilingData);
841
- metadata.actualDurations.push(id, actualDuration);
842
- metadata.maxActualDuration = Math.max(
843
- metadata.maxActualDuration,
844
- actualDuration
845
- );
846
- }
825
+ recordProfilingDurations(fiber);
826
}
827
}
828
@@ -993,7 +972,7 @@ export function attach(
972
}
973
}
974
996
- function recordTreeDuration(fiber: Fiber) {
975
+ function recordProfilingDurations(fiber: Fiber) {
976
const id = getFiberID(getPrimaryFiber(fiber));
977
const { actualDuration, treeBaseDuration } = fiber;
978
@@ -1003,8 +982,8 @@ export function attach(
982
const { alternate } = fiber;
983
984
if (
1006
- treeBaseDuration !==
1007
- (alternate ? alternate.treeBaseDuration : undefined)
985
+ alternate == null ||
986
+ treeBaseDuration !== alternate.treeBaseDuration
987
) {
988
// Tree base duration updates are included in the operations typed array.
989
// So we have to convert them from milliseconds to microseconds so we can send them as ints.
@@ -1012,18 +991,31 @@ export function attach(
991
(fiber.treeBaseDuration || 0) * 1000
992
);
993
pushOperation(TREE_OPERATION_UPDATE_TREE_BASE_DURATION);
1015
- pushOperation(getFiberID(getPrimaryFiber(fiber)));
994
+ pushOperation(id);
995
pushOperation(treeBaseDuration);
996
}
997
1019
- if (alternate ? hasDataChanged(alternate, fiber) : true) {
998
+ if (alternate == null || hasDataChanged(alternate, fiber)) {
999
if (actualDuration != null) {
1000
+ // The actual duration reported by React includes time spent working on children.
1001
+ // This is useful information, but it's also useful to be able to exclude child durations.
1002
+ // The frontend can't compute this, since the immediate children may have been filtered out.
1003
+ // So we need to do this on the backend.
1004
+ // Note that this calculated self duration is not the same thing as the base duration.
1005
+ // The two are calculated differently (tree duration does not accumulate).
1006
+ let selfDuration = actualDuration;
1007
+ let child = fiber.child;
1008
+ while (child !== null) {
1009
+ selfDuration -= child.actualDuration || 0;
1010
+ child = child.sibling;
1011
+ }
1012
+
1013
// If profiling is active, store durations for elements that were rendered during the commit.
1014
// Note that we should do this for any fiber we performed work on, regardless of its actualDuration value.
1015
// In some cases actualDuration might be 0 for fibers we worked on (particularly if we're using Date.now)
1016
// In other cases (e.g. Memo) actualDuration might be greater than 0 even if we "bailed out".
1017
const metadata = ((currentCommitProfilingMetadata: any): CommitProfilingData);
1026
- metadata.actualDurations.push(id, actualDuration);
1018
+ metadata.durations.push(id, actualDuration, selfDuration);
1019
metadata.maxActualDuration = Math.max(
1020
metadata.maxActualDuration,
1021
actualDuration
@@ -1205,7 +1197,7 @@ export function attach(
1197
if (shouldIncludeInTree) {
1198
const isProfilingSupported = nextFiber.hasOwnProperty('treeBaseDuration');
1199
if (isProfilingSupported) {
1208
- recordTreeDuration(nextFiber);
1200
+ recordProfilingDurations(nextFiber);
1201
}
1202
}
1203
if (shouldResetChildren) {
@@ -1267,7 +1259,7 @@ export function attach(
1259
// If profiling is active, store commit time and duration, and the current interactions.
1260
// The frontend may request this information after profiling has stopped.
1261
currentCommitProfilingMetadata = {
1270
- actualDurations: [],
1262
+ durations: [],
1263
commitTime: performance.now() - profilingStartTime,
1264
interactions: Array.from(root.memoizedInteractions).map(
1265
(interaction: InteractionBackend) => ({
@@ -1309,7 +1301,7 @@ export function attach(
1301
// If profiling is active, store commit time and duration, and the current interactions.
1302
// The frontend may request this information after profiling has stopped.
1303
currentCommitProfilingMetadata = {
1312
- actualDurations: [],
1304
+ durations: [],
1305
commitTime: performance.now() - profilingStartTime,
1306
interactions: Array.from(root.memoizedInteractions).map(
1307
(interaction: InteractionBackend) => ({
@@ -1960,8 +1952,8 @@ export function attach(
1952
}
1953
1954
type CommitProfilingData = {|
1963
- actualDurations: Array<number>,
1955
commitTime: number,
1956
+ durations: Array<number>,
1957
interactions: Array<InteractionBackend>,
1958
maxActualDuration: number,
1959
|};
@@ -1987,8 +1979,8 @@ export function attach(
1979
if (commitProfilingData != null) {
1980
return {
1981
commitIndex,
1982
+ durations: commitProfilingData.durations,
1983
interactions: commitProfilingData.interactions,
1991
- actualDurations: commitProfilingData.actualDurations,
1984
rootID,
1985
};
1986
}
@@ -2001,7 +1993,7 @@ export function attach(
1993
return {
1994
commitIndex,
1995
interactions: [],
2004
- actualDurations: [],
1996
+ durations: [],
1997
rootID,
1998
};
1999
}
@@ -2015,10 +2007,10 @@ export function attach(
2007
);
2008
if (commitProfilingMetadata != null) {
2009
const commitDurations = [];
2018
- commitProfilingMetadata.forEach(({ actualDurations }, commitIndex) => {
2019
- for (let i = 0; i < actualDurations.length; i += 2) {
2020
- if (actualDurations[i] === fiberID) {
2021
- commitDurations.push(commitIndex, actualDurations[i + 1]);
2010
+ commitProfilingMetadata.forEach(({ durations }, commitIndex) => {
2011
+ for (let i = 0; i < durations.length; i += 3) {
2012
+ if (durations[i] === fiberID) {
2013
+ commitDurations.push(commitIndex, durations[i + 2]);
2014
break;
2015
}
2016
}
src/backend/types.js
+2
-1
@@ -122,8 +122,9 @@ export type InteractionBackend = {|
122
|};
123
124
export type CommitDetailsBackend = {|
125
- actualDurations: Array<number>,
125
commitIndex: number,
126
+ // Tuple of id, actual duration, and (computed) self duration
127
+ durations: Array<number>,
128
interactions: Array<InteractionBackend>,
129
rootID: number,
130
|};
src/devtools/ProfilingCache.js
+12
-7
@@ -127,6 +127,7 @@ export default class ProfilingCache {
127
rootID,
128
commitIndex,
129
actualDurations: new Map(),
130
+ selfDurations: new Map(),
131
interactions: [],
132
});
133
});
@@ -147,10 +148,10 @@ export default class ProfilingCache {
148
const { commitDetails } = (importedProfilingData: any);
149
if (commitDetails != null) {
150
const commitDurations = [];
150
- commitDetails.forEach(({ actualDurations }, commitIndex) => {
151
- for (let i = 0; i < actualDurations.length; i += 2) {
152
- if (actualDurations[i] === fiberID) {
153
- commitDurations.push(commitIndex, actualDurations[i + 1]);
151
+ commitDetails.forEach(({ durations }, commitIndex) => {
152
+ for (let i = 0; i < durations.length; i += 3) {
153
+ if (durations[i] === fiberID) {
154
+ commitDurations.push(commitIndex, durations[i + 2]);
155
break;
156
}
157
}
@@ -332,7 +333,7 @@ export default class ProfilingCache {
333
334
onCommitDetails = ({
335
commitIndex,
335
- actualDurations,
336
+ durations,
337
interactions,
338
rootID,
339
}: CommitDetailsBackend) => {
@@ -342,14 +343,18 @@ export default class ProfilingCache {
343
this._pendingCommitDetailsMap.delete(key);
344
345
const actualDurationsMap = new Map();
345
- for (let i = 0; i < actualDurations.length; i += 2) {
346
- actualDurationsMap.set(actualDurations[i], actualDurations[i + 1]);
346
+ const selfDurationsMap = new Map();
347
+ for (let i = 0; i < durations.length; i += 3) {
348
+ const id = durations[i];
349
+ actualDurationsMap.set(id, durations[i + 1]);
350
+ selfDurationsMap.set(id, durations[i + 2]);
351
}
352
353
resolve({
354
rootID,
355
commitIndex,
356
actualDurations: actualDurationsMap,
357
+ selfDurations: selfDurationsMap,
358
interactions,
359
});
360
}
src/devtools/views/Profiler/FlamegraphChartBuilder.js
+3
-3
@@ -1,6 +1,6 @@
1
// @flow
2
3
-import { calculateSelfDuration, formatDuration } from './utils';
3
+import { formatDuration } from './utils';
4
5
import type { CommitDetailsFrontend, CommitTreeFrontend } from './types';
6
@@ -34,7 +34,7 @@ export function getChartData({
34
commitIndex: number,
35
commitTree: CommitTreeFrontend,
36
|}): ChartData {
37
- const { actualDurations, rootID } = commitDetails;
37
+ const { actualDurations, rootID, selfDurations } = commitDetails;
38
const { nodes } = commitTree;
39
40
const key = `${rootID}-${commitIndex}`;
@@ -60,7 +60,7 @@ export function getChartData({
60
const { children, displayName, key, treeBaseDuration } = node;
61
62
const actualDuration = actualDurations.get(id) || 0;
63
- const selfDuration = calculateSelfDuration(id, commitTree, commitDetails);
63
+ const selfDuration = selfDurations.get(id) || 0;
64
const didRender = actualDurations.has(id);
65
66
const name = displayName || 'Unknown';
src/devtools/views/Profiler/RankedChartBuilder.js
+3
-3
@@ -1,6 +1,6 @@
1
// @flow
2
3
-import { calculateSelfDuration, formatDuration } from './utils';
3
+import { formatDuration } from './utils';
4
5
import type { CommitDetailsFrontend, CommitTreeFrontend } from './types';
6
@@ -27,7 +27,7 @@ export function getChartData({
27
commitIndex: number,
28
commitTree: CommitTreeFrontend,
29
|}): ChartData {
30
- const { actualDurations, rootID } = commitDetails;
30
+ const { actualDurations, rootID, selfDurations } = commitDetails;
31
const { nodes } = commitTree;
32
33
const key = `${rootID}-${commitIndex}`;
@@ -49,7 +49,7 @@ export function getChartData({
49
if (node.parentID === 0) {
50
return;
51
}
52
- const selfDuration = calculateSelfDuration(id, commitTree, commitDetails);
52
+ const selfDuration = selfDurations.get(id) || 0;
53
maxSelfDuration = Math.max(maxSelfDuration, selfDuration);
54
55
const name = node.displayName || 'Unknown';
src/devtools/views/Profiler/types.js
+1
@@ -31,6 +31,7 @@ export type CommitDetailsFrontend = {|
31
rootID: number,
32
commitIndex: number,
33
actualDurations: Map<number, number>,
34
+ selfDurations: Map<number, number>,
35
interactions: Array<InteractionFrontend>,
36
|};
37
src/devtools/views/Profiler/utils.js
+1
-33
@@ -2,11 +2,7 @@
2
3
import { PROFILER_EXPORT_VERSION } from 'src/constants';
4
5
-import type {
6
- CommitDetailsFrontend,
7
- CommitTreeFrontend,
8
- ProfilingSnapshotNode,
9
-} from './types';
5
+import type { ProfilingSnapshotNode } from './types';
6
7
const commitGradient = [
8
'var(--color-commit-gradient-0)',
@@ -21,34 +17,6 @@ const commitGradient = [
17
'var(--color-commit-gradient-9)',
18
];
19
24
-export const calculateSelfDuration = (
25
- id: number,
26
- commitTree: CommitTreeFrontend,
27
- commitDetails: CommitDetailsFrontend
28
-): number => {
29
- const { actualDurations } = commitDetails;
30
- const { nodes } = commitTree;
31
-
32
- if (!actualDurations.has(id)) {
33
- return 0;
34
- }
35
-
36
- const node = nodes.get(id);
37
- if (node == null) {
38
- throw Error(`Could not find node with id "${id}" in commit tree`);
39
- }
40
-
41
- let selfDuration = actualDurations.get(id) || 0;
42
-
43
- node.children.forEach(childID => {
44
- if (actualDurations.has(childID)) {
45
- selfDuration -= actualDurations.get(childID) || 0;
46
- }
47
- });
48
-
49
- return selfDuration;
50
-};
51
-
20
export const prepareProfilingExport = (
21
profilingOperations: Map<number, Array<Uint32Array>>,
22
profilingSnapshots: Map<number, Map<number, ProfilingSnapshotNode>>,