Files
react/packages/react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder.js
T
Ruslan Lesiutin e7d213dfb0 feat[react-devtools]: display forget badge for components in profiling session (#29014)
# Summary
- `compiledWithForget` field for nodes is now propagated from the
backend to frontend profiler stores
- Corresponding node with such field will have a `` prefix displayed
before its displayName
<img width="1728" alt="Screenshot 2024-05-07 at 15 05 37"
src="https://github.com/facebook/react/assets/28902667/fe044d40-52cb-4169-867d-5a2d72e3275b">

- Badges are now displayed on the right panel when some fiber is
selected in a specific commit
<img width="1728" alt="Screenshot 2024-05-07 at 15 05 50"
src="https://github.com/facebook/react/assets/28902667/297ba5ca-404d-4172-b9bf-bfed7978afe5">

- Badges are also displayed when user hovers over some node in the tree
<img width="1728" alt="Screenshot 2024-05-07 at 15 25 22"
src="https://github.com/facebook/react/assets/28902667/bee47884-61d1-46b6-a483-717fc148893a">
2024-05-07 16:39:01 +01:00

108 lines
2.6 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import {
ElementTypeForwardRef,
ElementTypeMemo,
} from 'react-devtools-shared/src/frontend/types';
import {formatDuration} from './utils';
import ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
import type {CommitTree} from './types';
export type ChartNode = {
id: number,
label: string,
name: string,
value: number,
};
export type ChartData = {
maxValue: number,
nodes: Array<ChartNode>,
};
const cachedChartData: Map<string, ChartData> = new Map();
export function getChartData({
commitIndex,
commitTree,
profilerStore,
rootID,
}: {
commitIndex: number,
commitTree: CommitTree,
profilerStore: ProfilerStore,
rootID: number,
}): ChartData {
const commitDatum = profilerStore.getCommitData(rootID, commitIndex);
const {fiberActualDurations, fiberSelfDurations} = commitDatum;
const {nodes} = commitTree;
const chartDataKey = `${rootID}-${commitIndex}`;
if (cachedChartData.has(chartDataKey)) {
return ((cachedChartData.get(chartDataKey): any): ChartData);
}
let maxSelfDuration = 0;
const chartNodes: Array<ChartNode> = [];
fiberActualDurations.forEach((actualDuration, id) => {
const node = nodes.get(id);
if (node == null) {
throw Error(`Could not find node with id "${id}" in commit tree`);
}
const {displayName, key, parentID, type, compiledWithForget} = node;
// Don't show the root node in this chart.
if (parentID === 0) {
return;
}
const selfDuration = fiberSelfDurations.get(id) || 0;
maxSelfDuration = Math.max(maxSelfDuration, selfDuration);
const name = displayName || 'Anonymous';
const maybeKey = key !== null ? ` key="${key}"` : '';
const maybeForgetBadge = compiledWithForget ? '✨ ' : '';
let maybeBadge = '';
if (type === ElementTypeForwardRef) {
maybeBadge = ' (ForwardRef)';
} else if (type === ElementTypeMemo) {
maybeBadge = ' (Memo)';
}
const label = `${maybeForgetBadge}${name}${maybeBadge}${maybeKey} (${formatDuration(
selfDuration,
)}ms)`;
chartNodes.push({
id,
label,
name,
value: selfDuration,
});
});
const chartData = {
maxValue: maxSelfDuration,
nodes: chartNodes.sort((a, b) => b.value - a.value),
};
cachedChartData.set(chartDataKey, chartData);
return chartData;
}
export function invalidateChartData(): void {
cachedChartData.clear();
}