@samitouri / QOS-React-2 / commits / cf99c3ee6c

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>>,