mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove unstable scheduler/tracing API (#20037)
This commit is contained in:
@@ -16,10 +16,6 @@ import {
|
||||
getChartData as getFlamegraphChartData,
|
||||
invalidateChartData as invalidateFlamegraphChartData,
|
||||
} from 'react-devtools-shared/src/devtools/views/Profiler/FlamegraphChartBuilder';
|
||||
import {
|
||||
getChartData as getInteractionsChartData,
|
||||
invalidateChartData as invalidateInteractionsChartData,
|
||||
} from 'react-devtools-shared/src/devtools/views/Profiler/InteractionsChartBuilder';
|
||||
import {
|
||||
getChartData as getRankedChartData,
|
||||
invalidateChartData as invalidateRankedChartData,
|
||||
@@ -27,7 +23,6 @@ import {
|
||||
|
||||
import type {CommitTree} from 'react-devtools-shared/src/devtools/views/Profiler/types';
|
||||
import type {ChartData as FlamegraphChartData} from 'react-devtools-shared/src/devtools/views/Profiler/FlamegraphChartBuilder';
|
||||
import type {ChartData as InteractionsChartData} from 'react-devtools-shared/src/devtools/views/Profiler/InteractionsChartBuilder';
|
||||
import type {ChartData as RankedChartData} from 'react-devtools-shared/src/devtools/views/Profiler/RankedChartBuilder';
|
||||
|
||||
export default class ProfilingCache {
|
||||
@@ -92,16 +87,6 @@ export default class ProfilingCache {
|
||||
rootID,
|
||||
});
|
||||
|
||||
getInteractionsChartData = ({
|
||||
rootID,
|
||||
}: {|
|
||||
rootID: number,
|
||||
|}): InteractionsChartData =>
|
||||
getInteractionsChartData({
|
||||
profilerStore: this._profilerStore,
|
||||
rootID,
|
||||
});
|
||||
|
||||
getRankedChartData = ({
|
||||
commitIndex,
|
||||
commitTree,
|
||||
@@ -123,7 +108,6 @@ export default class ProfilingCache {
|
||||
|
||||
invalidateCommitTrees();
|
||||
invalidateFlamegraphChartData();
|
||||
invalidateInteractionsChartData();
|
||||
invalidateRankedChartData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ export type IconType =
|
||||
| 'error'
|
||||
| 'facebook'
|
||||
| 'flame-chart'
|
||||
| 'interactions'
|
||||
| 'profiler'
|
||||
| 'ranked-chart'
|
||||
| 'search'
|
||||
@@ -59,9 +58,6 @@ export default function Icon({className = '', type}: Props) {
|
||||
case 'flame-chart':
|
||||
pathData = PATH_FLAME_CHART;
|
||||
break;
|
||||
case 'interactions':
|
||||
pathData = PATH_INTERACTIONS;
|
||||
break;
|
||||
case 'profiler':
|
||||
pathData = PATH_PROFILER;
|
||||
break;
|
||||
@@ -138,14 +134,6 @@ const PATH_FLAME_CHART = `
|
||||
13.3541667,19.4702042 C13.3541667,20.1226027 12.7851952,20.6514763 12.0833333,20.6514763 Z
|
||||
`;
|
||||
|
||||
const PATH_INTERACTIONS = `
|
||||
M23 8c0 1.1-.9 2-2 2-.18 0-.35-.02-.51-.07l-3.56 3.55c.05.16.07.34.07.52 0 1.1-.9 2-2
|
||||
2s-2-.9-2-2c0-.18.02-.36.07-.52l-2.55-2.55c-.16.05-.34.07-.52.07s-.36-.02-.52-.07l-4.55
|
||||
4.56c.05.16.07.33.07.51 0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2c.18 0 .35.02.51.07l4.56-4.55C8.02
|
||||
9.36 8 9.18 8 9c0-1.1.9-2 2-2s2 .9 2 2c0 .18-.02.36-.07.52l2.55
|
||||
2.55c.16-.05.34-.07.52-.07s.36.02.52.07l3.55-3.56C19.02 8.35 19 8.18 19 8c0-1.1.9-2 2-2s2 .9 2 2z
|
||||
`;
|
||||
|
||||
const PATH_PROFILER = 'M5 9.2h3V19H5zM10.6 5h2.8v14h-2.8zm5.6 8H19v6h-2.8z';
|
||||
|
||||
const PATH_SEARCH = `
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
.Interaction,
|
||||
.SelectedInteraction {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.25rem;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.Interaction:hover {
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
|
||||
.SelectedInteraction {
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
|
||||
.Name {
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.Timeline {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.InteractionLine {
|
||||
position: absolute;
|
||||
height: 3px;
|
||||
background-color: var(--color-commit-did-not-render-fill);
|
||||
color: var(--color-commit-did-not-render-fill-text);
|
||||
border-radius: 0.125rem;
|
||||
}
|
||||
|
||||
.CommitBox {
|
||||
position: absolute;
|
||||
width: var(--interaction-commit-size);
|
||||
height: var(--interaction-commit-size);
|
||||
background-color: var(--color-commit-did-not-render-fill);
|
||||
color: var(--color-commit-did-not-render-fill-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 * as React from 'react';
|
||||
import {memo, useCallback} from 'react';
|
||||
import {areEqual} from 'react-window';
|
||||
import {getGradientColor} from './utils';
|
||||
|
||||
import styles from './InteractionListItem.css';
|
||||
|
||||
import type {ItemData} from './Interactions';
|
||||
|
||||
type Props = {
|
||||
data: ItemData,
|
||||
index: number,
|
||||
style: Object,
|
||||
...
|
||||
};
|
||||
|
||||
function InteractionListItem({data: itemData, index, style}: Props) {
|
||||
const {
|
||||
chartData,
|
||||
dataForRoot,
|
||||
labelWidth,
|
||||
scaleX,
|
||||
selectedInteractionID,
|
||||
selectCommitIndex,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
} = itemData;
|
||||
|
||||
const {commitData, interactionCommits} = dataForRoot;
|
||||
const {interactions, lastInteractionTime, maxCommitDuration} = chartData;
|
||||
|
||||
const interaction = interactions[index];
|
||||
if (interaction == null) {
|
||||
throw Error(`Could not find interaction #${index}`);
|
||||
}
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
selectInteraction(interaction.id);
|
||||
}, [interaction, selectInteraction]);
|
||||
|
||||
const commits = interactionCommits.get(interaction.id) || [];
|
||||
|
||||
const startTime = interaction.timestamp;
|
||||
const stopTime = lastInteractionTime;
|
||||
|
||||
const viewCommit = (commitIndex: number) => {
|
||||
selectTab('flame-chart');
|
||||
selectCommitIndex(commitIndex);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
selectedInteractionID === interaction.id
|
||||
? styles.SelectedInteraction
|
||||
: styles.Interaction
|
||||
}
|
||||
onClick={handleClick}
|
||||
style={style}>
|
||||
<div
|
||||
className={styles.Name}
|
||||
style={{maxWidth: labelWidth}}
|
||||
title={interaction.name}>
|
||||
{interaction.name}
|
||||
</div>
|
||||
<div
|
||||
className={styles.InteractionLine}
|
||||
style={{
|
||||
left: labelWidth + scaleX(startTime, 0),
|
||||
width: scaleX(stopTime - startTime, 0),
|
||||
}}
|
||||
/>
|
||||
{commits.map(commitIndex => (
|
||||
<div
|
||||
className={styles.CommitBox}
|
||||
key={commitIndex}
|
||||
onClick={() => viewCommit(commitIndex)}
|
||||
style={{
|
||||
backgroundColor: getGradientColor(
|
||||
Math.min(
|
||||
1,
|
||||
Math.max(
|
||||
0,
|
||||
commitData[commitIndex].duration / maxCommitDuration,
|
||||
),
|
||||
) || 0,
|
||||
),
|
||||
left: labelWidth + scaleX(commitData[commitIndex].timestamp, 0),
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo<Props>(InteractionListItem, areEqual);
|
||||
@@ -1,9 +0,0 @@
|
||||
.Container {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.FocusTarget:focus {
|
||||
outline: none;
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 * as React from 'react';
|
||||
import {useCallback, useContext, useMemo} from 'react';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import {FixedSizeList} from 'react-window';
|
||||
import {ProfilerContext} from './ProfilerContext';
|
||||
import InteractionListItem from './InteractionListItem';
|
||||
import NoInteractions from './NoInteractions';
|
||||
import {StoreContext} from '../context';
|
||||
import {scale} from './utils';
|
||||
|
||||
import styles from './Interactions.css';
|
||||
|
||||
import type {ProfilingDataForRootFrontend} from './types';
|
||||
import type {ChartData} from './InteractionsChartBuilder';
|
||||
import type {TabID} from './ProfilerContext';
|
||||
|
||||
export type ItemData = {|
|
||||
chartData: ChartData,
|
||||
dataForRoot: ProfilingDataForRootFrontend,
|
||||
labelWidth: number,
|
||||
scaleX: (value: number, fallbackValue: number) => number,
|
||||
selectedInteractionID: number | null,
|
||||
selectCommitIndex: (id: number | null) => void,
|
||||
selectInteraction: (id: number | null) => void,
|
||||
selectTab: (id: TabID) => void,
|
||||
|};
|
||||
|
||||
export default function InteractionsAutoSizer(_: {||}) {
|
||||
return (
|
||||
<div className={styles.Container}>
|
||||
<AutoSizer>
|
||||
{({height, width}) => <Interactions height={height} width={width} />}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Interactions({height, width}: {|height: number, width: number|}) {
|
||||
const {
|
||||
rootID,
|
||||
selectedInteractionID,
|
||||
selectInteraction,
|
||||
selectCommitIndex,
|
||||
selectTab,
|
||||
} = useContext(ProfilerContext);
|
||||
const {profilerStore} = useContext(StoreContext);
|
||||
const {profilingCache} = profilerStore;
|
||||
|
||||
const dataForRoot = profilerStore.getDataForRoot(((rootID: any): number));
|
||||
|
||||
const chartData = profilingCache.getInteractionsChartData({
|
||||
rootID: ((rootID: any): number),
|
||||
});
|
||||
|
||||
const {interactions} = chartData;
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
event => {
|
||||
let index;
|
||||
switch (event.key) {
|
||||
case 'ArrowDown':
|
||||
index = interactions.findIndex(
|
||||
interaction => interaction.id === selectedInteractionID,
|
||||
);
|
||||
selectInteraction(Math.min(interactions.length - 1, index + 1));
|
||||
event.stopPropagation();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
index = interactions.findIndex(
|
||||
interaction => interaction.id === selectedInteractionID,
|
||||
);
|
||||
selectInteraction(Math.max(0, index - 1));
|
||||
event.stopPropagation();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
[interactions, selectedInteractionID, selectInteraction],
|
||||
);
|
||||
|
||||
const itemData = useMemo<ItemData>(() => {
|
||||
const interactionCommitSize = parseInt(
|
||||
getComputedStyle((document.body: any)).getPropertyValue(
|
||||
'--interaction-commit-size',
|
||||
),
|
||||
10,
|
||||
);
|
||||
const interactionLabelWidth = parseInt(
|
||||
getComputedStyle((document.body: any)).getPropertyValue(
|
||||
'--interaction-label-width',
|
||||
),
|
||||
10,
|
||||
);
|
||||
|
||||
const labelWidth = Math.min(interactionLabelWidth, width / 5);
|
||||
const timelineWidth = width - labelWidth - interactionCommitSize;
|
||||
|
||||
return {
|
||||
chartData,
|
||||
dataForRoot,
|
||||
labelWidth,
|
||||
scaleX: scale(0, chartData.lastInteractionTime, 0, timelineWidth),
|
||||
selectedInteractionID,
|
||||
selectCommitIndex,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
};
|
||||
}, [
|
||||
chartData,
|
||||
dataForRoot,
|
||||
selectedInteractionID,
|
||||
selectCommitIndex,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
width,
|
||||
]);
|
||||
|
||||
// If a commit contains no fibers with an actualDuration > 0,
|
||||
// Display a fallback message.
|
||||
if (interactions.length === 0) {
|
||||
return <NoInteractions height={height} width={width} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.FocusTarget} onKeyDown={handleKeyDown} tabIndex={0}>
|
||||
<FixedSizeList
|
||||
height={height}
|
||||
itemCount={interactions.length}
|
||||
itemData={itemData}
|
||||
itemSize={30}
|
||||
width={width}>
|
||||
{InteractionListItem}
|
||||
</FixedSizeList>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 ProfilerStore from 'react-devtools-shared/src/devtools/ProfilerStore';
|
||||
|
||||
import type {Interaction} from './types';
|
||||
|
||||
export type ChartData = {|
|
||||
interactions: Array<Interaction>,
|
||||
lastInteractionTime: number,
|
||||
maxCommitDuration: number,
|
||||
|};
|
||||
|
||||
const cachedChartData: Map<number, ChartData> = new Map();
|
||||
|
||||
export function getChartData({
|
||||
profilerStore,
|
||||
rootID,
|
||||
}: {|
|
||||
profilerStore: ProfilerStore,
|
||||
rootID: number,
|
||||
|}): ChartData {
|
||||
if (cachedChartData.has(rootID)) {
|
||||
return ((cachedChartData.get(rootID): any): ChartData);
|
||||
}
|
||||
|
||||
const dataForRoot = profilerStore.getDataForRoot(rootID);
|
||||
if (dataForRoot == null) {
|
||||
throw Error(`Could not find profiling data for root "${rootID}"`);
|
||||
}
|
||||
|
||||
const {commitData, interactions} = dataForRoot;
|
||||
|
||||
const lastInteractionTime =
|
||||
commitData.length > 0 ? commitData[commitData.length - 1].timestamp : 0;
|
||||
|
||||
let maxCommitDuration = 0;
|
||||
|
||||
commitData.forEach(commitDatum => {
|
||||
maxCommitDuration = Math.max(maxCommitDuration, commitDatum.duration);
|
||||
});
|
||||
|
||||
const chartData = {
|
||||
interactions: Array.from(interactions.values()),
|
||||
lastInteractionTime,
|
||||
maxCommitDuration,
|
||||
};
|
||||
|
||||
cachedChartData.set(rootID, chartData);
|
||||
|
||||
return chartData;
|
||||
}
|
||||
|
||||
export function invalidateChartData(): void {
|
||||
cachedChartData.clear();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
.NoInteractions {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.Header {
|
||||
font-size: var(--font-size-sans-large);
|
||||
}
|
||||
|
||||
.Link {
|
||||
color: var(--color-button);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 * as React from 'react';
|
||||
|
||||
import styles from './NoInteractions.css';
|
||||
|
||||
export default function NoInteractions({
|
||||
height,
|
||||
width,
|
||||
}: {|
|
||||
height: number,
|
||||
width: number,
|
||||
|}) {
|
||||
return (
|
||||
<div className={styles.NoInteractions} style={{height, width}}>
|
||||
<p className={styles.Header}>No interactions were recorded.</p>
|
||||
<p>
|
||||
<a
|
||||
className={styles.Link}
|
||||
href="https://reactjs.org/link/interaction-tracing"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank">
|
||||
Learn more about the interaction tracing API here.
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -15,14 +15,12 @@ import TabBar from '../TabBar';
|
||||
import ClearProfilingDataButton from './ClearProfilingDataButton';
|
||||
import CommitFlamegraph from './CommitFlamegraph';
|
||||
import CommitRanked from './CommitRanked';
|
||||
import Interactions from './Interactions';
|
||||
import RootSelector from './RootSelector';
|
||||
import RecordToggle from './RecordToggle';
|
||||
import ReloadAndProfileButton from './ReloadAndProfileButton';
|
||||
import ProfilingImportExportButtons from './ProfilingImportExportButtons';
|
||||
import SnapshotSelector from './SnapshotSelector';
|
||||
import SidebarCommitInfo from './SidebarCommitInfo';
|
||||
import SidebarInteractions from './SidebarInteractions';
|
||||
import SidebarSelectedFiberInfo from './SidebarSelectedFiberInfo';
|
||||
import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal';
|
||||
import SettingsModalContextToggle from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContextToggle';
|
||||
@@ -53,9 +51,6 @@ function Profiler(_: {||}) {
|
||||
case 'ranked-chart':
|
||||
view = <CommitRanked />;
|
||||
break;
|
||||
case 'interactions':
|
||||
view = <Interactions />;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -72,9 +67,6 @@ function Profiler(_: {||}) {
|
||||
let sidebar = null;
|
||||
if (!isProfiling && !isProcessingData && didRecordCommits) {
|
||||
switch (selectedTabID) {
|
||||
case 'interactions':
|
||||
sidebar = <SidebarInteractions />;
|
||||
break;
|
||||
case 'flame-chart':
|
||||
case 'ranked-chart':
|
||||
// TRICKY
|
||||
@@ -148,12 +140,6 @@ const tabs = [
|
||||
label: 'Ranked',
|
||||
title: 'Ranked chart',
|
||||
},
|
||||
{
|
||||
id: 'interactions',
|
||||
icon: 'interactions',
|
||||
label: 'Interactions',
|
||||
title: 'Profiled interactions',
|
||||
},
|
||||
];
|
||||
|
||||
const NoProfilingData = () => (
|
||||
|
||||
+1
-17
@@ -19,7 +19,7 @@ import {StoreContext} from '../context';
|
||||
|
||||
import type {ProfilingDataFrontend} from './types';
|
||||
|
||||
export type TabID = 'flame-chart' | 'ranked-chart' | 'interactions';
|
||||
export type TabID = 'flame-chart' | 'ranked-chart';
|
||||
|
||||
export type Context = {|
|
||||
// Which tab is selected in the Profiler UI?
|
||||
@@ -64,10 +64,6 @@ export type Context = {|
|
||||
selectedFiberID: number | null,
|
||||
selectedFiberName: string | null,
|
||||
selectFiber: (id: number | null, name: string | null) => void,
|
||||
|
||||
// Which interaction is currently selected in the Interactions graph?
|
||||
selectedInteractionID: number | null,
|
||||
selectInteraction: (id: number | null) => void,
|
||||
|};
|
||||
|
||||
const ProfilerContext = createContext<Context>(((null: any): Context));
|
||||
@@ -216,9 +212,6 @@ function ProfilerContextController({children}: Props) {
|
||||
null,
|
||||
);
|
||||
const [selectedTabID, selectTab] = useState<TabID>('flame-chart');
|
||||
const [selectedInteractionID, selectInteraction] = useState<number | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
if (isProfiling) {
|
||||
batchedUpdates(() => {
|
||||
@@ -229,9 +222,6 @@ function ProfilerContextController({children}: Props) {
|
||||
selectFiberID(null);
|
||||
selectFiberName(null);
|
||||
}
|
||||
if (selectedInteractionID !== null) {
|
||||
selectInteraction(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -262,9 +252,6 @@ function ProfilerContextController({children}: Props) {
|
||||
selectedFiberID,
|
||||
selectedFiberName,
|
||||
selectFiber,
|
||||
|
||||
selectedInteractionID,
|
||||
selectInteraction,
|
||||
}),
|
||||
[
|
||||
selectedTabID,
|
||||
@@ -293,9 +280,6 @@ function ProfilerContextController({children}: Props) {
|
||||
selectedFiberID,
|
||||
selectedFiberName,
|
||||
selectFiber,
|
||||
|
||||
selectedInteractionID,
|
||||
selectInteraction,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@@ -23,33 +23,6 @@
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
|
||||
.NoInteractions {
|
||||
color: var(--color-dim);
|
||||
}
|
||||
|
||||
.Interactions {
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
.NoInteractions,
|
||||
.Interaction {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
color: var(--color-text);
|
||||
}
|
||||
.Interaction:focus,
|
||||
.Interaction:hover {
|
||||
outline: none;
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
|
||||
.NoInteractions {
|
||||
color: var(--color-dim);
|
||||
}
|
||||
|
||||
.Label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
+1
-36
@@ -20,12 +20,7 @@ import styles from './SidebarCommitInfo.css';
|
||||
export type Props = {||};
|
||||
|
||||
export default function SidebarCommitInfo(_: Props) {
|
||||
const {
|
||||
selectedCommitIndex,
|
||||
rootID,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
} = useContext(ProfilerContext);
|
||||
const {selectedCommitIndex, rootID} = useContext(ProfilerContext);
|
||||
|
||||
const {profilerStore} = useContext(StoreContext);
|
||||
|
||||
@@ -33,22 +28,15 @@ export default function SidebarCommitInfo(_: Props) {
|
||||
return <div className={styles.NothingSelected}>Nothing selected</div>;
|
||||
}
|
||||
|
||||
const {interactions} = profilerStore.getDataForRoot(rootID);
|
||||
const {
|
||||
duration,
|
||||
effectDuration,
|
||||
interactionIDs,
|
||||
passiveEffectDuration,
|
||||
priorityLevel,
|
||||
timestamp,
|
||||
updaters,
|
||||
} = profilerStore.getCommitData(rootID, selectedCommitIndex);
|
||||
|
||||
const viewInteraction = interactionID => {
|
||||
selectTab('interactions');
|
||||
selectInteraction(interactionID);
|
||||
};
|
||||
|
||||
const hasCommitPhaseDurations =
|
||||
effectDuration !== null || passiveEffectDuration !== null;
|
||||
|
||||
@@ -120,29 +108,6 @@ export default function SidebarCommitInfo(_: Props) {
|
||||
<Updaters commitTree={commitTree} updaters={updaters} />
|
||||
</li>
|
||||
)}
|
||||
|
||||
<li className={styles.Interactions}>
|
||||
<label className={styles.Label}>Interactions</label>:
|
||||
<div className={styles.InteractionList}>
|
||||
{interactionIDs.length === 0 ? (
|
||||
<div className={styles.NoInteractions}>(none)</div>
|
||||
) : null}
|
||||
{interactionIDs.map(interactionID => {
|
||||
const interaction = interactions.get(interactionID);
|
||||
if (interaction == null) {
|
||||
throw Error(`Invalid interaction "${interactionID}"`);
|
||||
}
|
||||
return (
|
||||
<button
|
||||
key={interactionID}
|
||||
className={styles.Interaction}
|
||||
onClick={() => viewInteraction(interactionID)}>
|
||||
{interaction.name}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Fragment>
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
.Toolbar {
|
||||
height: 2.25rem;
|
||||
padding: 0 0.5rem;
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Content {
|
||||
padding: 0.5rem;
|
||||
user-select: none;
|
||||
border-top: 1px solid var(--color-border);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.Name {
|
||||
font-size: var(--font-size-sans-large);
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.NothingSelected {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
color: var(--color-dim);
|
||||
}
|
||||
|
||||
.Commits {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.List {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ListItem {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.ListItem:hover {
|
||||
background-color: var(--color-background-hover);
|
||||
}
|
||||
|
||||
.CommitBox {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 * as React from 'react';
|
||||
import {Fragment, useContext} from 'react';
|
||||
import {ProfilerContext} from './ProfilerContext';
|
||||
import {formatDuration, formatTime} from './utils';
|
||||
import {StoreContext} from '../context';
|
||||
import {getGradientColor} from './utils';
|
||||
|
||||
import styles from './SidebarInteractions.css';
|
||||
|
||||
export type Props = {||};
|
||||
|
||||
export default function SidebarInteractions(_: Props) {
|
||||
const {
|
||||
selectedInteractionID,
|
||||
rootID,
|
||||
selectCommitIndex,
|
||||
selectTab,
|
||||
} = useContext(ProfilerContext);
|
||||
|
||||
const {profilerStore} = useContext(StoreContext);
|
||||
const {profilingCache} = profilerStore;
|
||||
|
||||
if (selectedInteractionID === null) {
|
||||
return <div className={styles.NothingSelected}>Nothing selected</div>;
|
||||
}
|
||||
|
||||
const {interactionCommits, interactions} = profilerStore.getDataForRoot(
|
||||
((rootID: any): number),
|
||||
);
|
||||
const interaction = interactions.get(selectedInteractionID);
|
||||
if (interaction == null) {
|
||||
throw Error(
|
||||
`Could not find interaction by selected interaction id "${selectedInteractionID}"`,
|
||||
);
|
||||
}
|
||||
|
||||
const {maxCommitDuration} = profilingCache.getInteractionsChartData({
|
||||
rootID: ((rootID: any): number),
|
||||
});
|
||||
|
||||
const viewCommit = (commitIndex: number) => {
|
||||
selectTab('flame-chart');
|
||||
selectCommitIndex(commitIndex);
|
||||
};
|
||||
|
||||
const listItems: Array<React$Node> = [];
|
||||
const commitIndices = interactionCommits.get(selectedInteractionID);
|
||||
if (commitIndices != null) {
|
||||
commitIndices.forEach(commitIndex => {
|
||||
const {duration, timestamp} = profilerStore.getCommitData(
|
||||
((rootID: any): number),
|
||||
commitIndex,
|
||||
);
|
||||
|
||||
listItems.push(
|
||||
<li
|
||||
key={commitIndex}
|
||||
className={styles.ListItem}
|
||||
onClick={() => viewCommit(commitIndex)}>
|
||||
<div
|
||||
className={styles.CommitBox}
|
||||
style={{
|
||||
backgroundColor: getGradientColor(
|
||||
Math.min(1, Math.max(0, duration / maxCommitDuration)) || 0,
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
timestamp: {formatTime(timestamp)}s
|
||||
<br />
|
||||
duration: {formatDuration(duration)}ms
|
||||
</div>
|
||||
</li>,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={styles.Toolbar}>
|
||||
<div className={styles.Name} title={interaction.name}>
|
||||
{interaction.name}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.Content}>
|
||||
<div className={styles.Commits}>Commits:</div>
|
||||
<ul className={styles.List}>{listItems}</ul>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
@@ -8,7 +8,5 @@
|
||||
*/
|
||||
|
||||
export const barWidthThreshold = 2;
|
||||
export const interactionCommitSize = 10;
|
||||
export const interactionLabelWidth = 200;
|
||||
export const maxBarWidth = 30;
|
||||
export const minBarWidth = 5;
|
||||
|
||||
@@ -26,12 +26,6 @@ export type CommitTree = {|
|
||||
rootID: number,
|
||||
|};
|
||||
|
||||
export type Interaction = {|
|
||||
id: number,
|
||||
name: string,
|
||||
timestamp: number,
|
||||
|};
|
||||
|
||||
export type SnapshotNode = {|
|
||||
id: number,
|
||||
children: Array<number>,
|
||||
@@ -69,9 +63,6 @@ export type CommitDataFrontend = {|
|
||||
// Fibers that did not render will not have entries in this Map.
|
||||
fiberSelfDurations: Map<number, number>,
|
||||
|
||||
// Which interactions (IDs) were associated with this commit.
|
||||
interactionIDs: Array<number>,
|
||||
|
||||
// How long was the passive commit phase?
|
||||
// Note that not all builds of React expose this property.
|
||||
passiveEffectDuration: number | null,
|
||||
@@ -98,12 +89,6 @@ export type ProfilingDataForRootFrontend = {|
|
||||
// This info can be used along with commitOperations to reconstruct the tree for any commit.
|
||||
initialTreeBaseDurations: Map<number, number>,
|
||||
|
||||
// All interactions recorded (for this root) during the current session.
|
||||
interactionCommits: Map<number, Array<number>>,
|
||||
|
||||
// All interactions recorded (for this root) during the current session.
|
||||
interactions: Map<number, Interaction>,
|
||||
|
||||
// List of tree mutation that occur during profiling.
|
||||
// These mutations can be used along with initial snapshots to reconstruct the tree for any commit.
|
||||
operations: Array<Array<number>>,
|
||||
@@ -131,7 +116,6 @@ export type CommitDataExport = {|
|
||||
fiberActualDurations: Array<[number, number]>,
|
||||
// Tuple of fiber ID and computed "self" duration
|
||||
fiberSelfDurations: Array<[number, number]>,
|
||||
interactionIDs: Array<number>,
|
||||
passiveEffectDuration: number | null,
|
||||
priorityLevel: string | null,
|
||||
timestamp: number,
|
||||
@@ -143,9 +127,6 @@ export type ProfilingDataForRootExport = {|
|
||||
displayName: string,
|
||||
// Tuple of Fiber ID and base duration
|
||||
initialTreeBaseDurations: Array<[number, number]>,
|
||||
// Tuple of Interaction ID and commit indices
|
||||
interactionCommits: Array<[number, Array<number>]>,
|
||||
interactions: Array<[number, Interaction]>,
|
||||
operations: Array<Array<number>>,
|
||||
rootID: number,
|
||||
snapshots: Array<[number, SnapshotNode]>,
|
||||
|
||||
@@ -43,14 +43,7 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
|
||||
|
||||
dataBackends.forEach(dataBackend => {
|
||||
dataBackend.dataForRoots.forEach(
|
||||
({
|
||||
commitData,
|
||||
displayName,
|
||||
initialTreeBaseDurations,
|
||||
interactionCommits,
|
||||
interactions,
|
||||
rootID,
|
||||
}) => {
|
||||
({commitData, displayName, initialTreeBaseDurations, rootID}) => {
|
||||
const operations = operationsByRootID.get(rootID);
|
||||
if (operations == null) {
|
||||
throw Error(
|
||||
@@ -66,12 +59,7 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
|
||||
}
|
||||
|
||||
// Do not filter empty commits from the profiler data!
|
||||
// We used to do this, but it was error prone (see #18798).
|
||||
// A commit may appear to be empty (no actual durations) because of component filters,
|
||||
// but filtering these empty commits causes interaction commit indices to be off by N.
|
||||
// This not only corrupts the resulting data, but also potentially causes runtime errors.
|
||||
//
|
||||
// For that matter, hiding "empty" commits might cause confusion too.
|
||||
// Hiding "empty" commits might cause confusion too.
|
||||
// A commit *did happen* even if none of the components the Profiler is showing were involved.
|
||||
const convertedCommitData = commitData.map(
|
||||
(commitDataBackend, commitIndex) => ({
|
||||
@@ -85,7 +73,6 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
|
||||
commitDataBackend.fiberActualDurations,
|
||||
),
|
||||
fiberSelfDurations: new Map(commitDataBackend.fiberSelfDurations),
|
||||
interactionIDs: commitDataBackend.interactionIDs,
|
||||
passiveEffectDuration: commitDataBackend.passiveEffectDuration,
|
||||
priorityLevel: commitDataBackend.priorityLevel,
|
||||
timestamp: commitDataBackend.timestamp,
|
||||
@@ -113,8 +100,6 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
|
||||
commitData: convertedCommitData,
|
||||
displayName,
|
||||
initialTreeBaseDurations: new Map(initialTreeBaseDurations),
|
||||
interactionCommits: new Map(interactionCommits),
|
||||
interactions: new Map(interactions),
|
||||
operations,
|
||||
rootID,
|
||||
snapshots,
|
||||
@@ -144,8 +129,6 @@ export function prepareProfilingDataFrontendFromExport(
|
||||
commitData,
|
||||
displayName,
|
||||
initialTreeBaseDurations,
|
||||
interactionCommits,
|
||||
interactions,
|
||||
operations,
|
||||
rootID,
|
||||
snapshots,
|
||||
@@ -158,7 +141,6 @@ export function prepareProfilingDataFrontendFromExport(
|
||||
effectDuration,
|
||||
fiberActualDurations,
|
||||
fiberSelfDurations,
|
||||
interactionIDs,
|
||||
passiveEffectDuration,
|
||||
priorityLevel,
|
||||
timestamp,
|
||||
@@ -170,7 +152,6 @@ export function prepareProfilingDataFrontendFromExport(
|
||||
effectDuration,
|
||||
fiberActualDurations: new Map(fiberActualDurations),
|
||||
fiberSelfDurations: new Map(fiberSelfDurations),
|
||||
interactionIDs,
|
||||
passiveEffectDuration,
|
||||
priorityLevel,
|
||||
timestamp,
|
||||
@@ -179,8 +160,6 @@ export function prepareProfilingDataFrontendFromExport(
|
||||
),
|
||||
displayName,
|
||||
initialTreeBaseDurations: new Map(initialTreeBaseDurations),
|
||||
interactionCommits: new Map(interactionCommits),
|
||||
interactions: new Map(interactions),
|
||||
operations,
|
||||
rootID,
|
||||
snapshots: new Map(snapshots),
|
||||
@@ -201,8 +180,6 @@ export function prepareProfilingDataExport(
|
||||
commitData,
|
||||
displayName,
|
||||
initialTreeBaseDurations,
|
||||
interactionCommits,
|
||||
interactions,
|
||||
operations,
|
||||
rootID,
|
||||
snapshots,
|
||||
@@ -215,7 +192,6 @@ export function prepareProfilingDataExport(
|
||||
effectDuration,
|
||||
fiberActualDurations,
|
||||
fiberSelfDurations,
|
||||
interactionIDs,
|
||||
passiveEffectDuration,
|
||||
priorityLevel,
|
||||
timestamp,
|
||||
@@ -229,7 +205,6 @@ export function prepareProfilingDataExport(
|
||||
effectDuration,
|
||||
fiberActualDurations: Array.from(fiberActualDurations.entries()),
|
||||
fiberSelfDurations: Array.from(fiberSelfDurations.entries()),
|
||||
interactionIDs,
|
||||
passiveEffectDuration,
|
||||
priorityLevel,
|
||||
timestamp,
|
||||
@@ -240,8 +215,6 @@ export function prepareProfilingDataExport(
|
||||
initialTreeBaseDurations: Array.from(
|
||||
initialTreeBaseDurations.entries(),
|
||||
),
|
||||
interactionCommits: Array.from(interactionCommits.entries()),
|
||||
interactions: Array.from(interactions.entries()),
|
||||
operations,
|
||||
rootID,
|
||||
snapshots: Array.from(snapshots.entries()),
|
||||
|
||||
@@ -211,8 +211,4 @@
|
||||
Courier, monospace;
|
||||
--font-family-sans: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica,
|
||||
Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
||||
|
||||
/* Constant values shared between JS and CSS */
|
||||
--interaction-commit-size: 10px;
|
||||
--interaction-label-width: 200px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user