main
js 107 lines 2.57 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import {
11 ElementTypeForwardRef,
12 ElementTypeMemo,
13 } from 'react-devtools-shared/src/frontend/types';
14 import {formatDuration} from './utils';
15 import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
16
17 import type {CommitTree} from './types';
18
19 export type ChartNode = {
20 id: number,
21 label: string,
22 name: string,
23 value: number,
24 };
25
26 export type ChartData = {
27 maxValue: number,
28 nodes: Array<ChartNode>,
29 };
30
31 const cachedChartData: Map<string, ChartData> = new Map();
32
33 export function getChartData({
34 commitIndex,
35 commitTree,
36 profilerStore,
37 rootID,
38 }: {
39 commitIndex: number,
40 commitTree: CommitTree,
41 profilerStore: ProfilerStore,
42 rootID: number,
43 }): ChartData {
44 const commitDatum = profilerStore.getCommitData(rootID, commitIndex);
45
46 const {fiberActualDurations, fiberSelfDurations} = commitDatum;
47 const {nodes} = commitTree;
48
49 const chartDataKey = `${rootID}-${commitIndex}`;
50 if (cachedChartData.has(chartDataKey)) {
51 return cachedChartData.get(chartDataKey) as any as ChartData;
52 }
53
54 let maxSelfDuration = 0;
55
56 const chartNodes: Array<ChartNode> = [];
57 fiberActualDurations.forEach((actualDuration, id) => {
58 const node = nodes.get(id);
59
60 if (node == null) {
61 throw Error(`Could not find node with id "${id}" in commit tree`);
62 }
63
64 const {displayName, key, parentID, type, compiledWithForget} = node;
65
66 // Don't show the root node in this chart.
67 if (parentID === 0) {
68 return;
69 }
70 const selfDuration = fiberSelfDurations.get(id) || 0;
71 maxSelfDuration = Math.max(maxSelfDuration, selfDuration);
72
73 const name = displayName || 'Anonymous';
74 const maybeKey = key !== null ? ` key="${key}"` : '';
75 const maybeForgetBadge = compiledWithForget ? '' : '';
76
77 let maybeBadge = '';
78 if (type === ElementTypeForwardRef) {
79 maybeBadge = ' (ForwardRef)';
80 } else if (type === ElementTypeMemo) {
81 maybeBadge = ' (Memo)';
82 }
83
84 const label = `${maybeForgetBadge}${name}${maybeBadge}${maybeKey} (${formatDuration(
85 selfDuration,
86 )}ms)`;
87 chartNodes.push({
88 id,
89 label,
90 name,
91 value: selfDuration,
92 });
93 });
94
95 const chartData = {
96 maxValue: maxSelfDuration,
97 nodes: chartNodes.sort((a, b) => b.value - a.value),
98 };
99
100 cachedChartData.set(chartDataKey, chartData);
101
102 return chartData;
103 }
104
105 export function invalidateChartData(): void {
106 cachedChartData.clear();
107 }