mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Clicking commits and interactions link to each other
This commit is contained in:
@@ -21,6 +21,7 @@ export default function InteractionTracing() {
|
||||
);
|
||||
});
|
||||
}, [count]);
|
||||
|
||||
const handleCascadingUpdate = useCallback(() => {
|
||||
trace('cascade', performance.now(), () => {
|
||||
setTimeout(
|
||||
@@ -35,6 +36,19 @@ export default function InteractionTracing() {
|
||||
});
|
||||
}, [count]);
|
||||
|
||||
const handleMultiple = useCallback(() => {
|
||||
trace('first', performance.now(), () => {
|
||||
trace('second', performance.now(), () => {
|
||||
setTimeout(
|
||||
wrap(() => {
|
||||
setCount(count + 1);
|
||||
}),
|
||||
count * 100
|
||||
);
|
||||
});
|
||||
});
|
||||
}, [count]);
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldCascade) {
|
||||
setTimeout(
|
||||
@@ -53,6 +67,7 @@ export default function InteractionTracing() {
|
||||
<button onClick={handleCascadingUpdate}>
|
||||
Cascading Update ({count}, {shouldCascade ? 'true' : 'false'})
|
||||
</button>
|
||||
<button onClick={handleMultiple}>Multiple</button>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ function InteractionListItem({ data: itemData, index, style }: Props) {
|
||||
profilingSummary,
|
||||
scaleX,
|
||||
selectedInteractionID,
|
||||
selectCommitIndex,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
} = itemData;
|
||||
|
||||
const { maxCommitDuration } = chartData;
|
||||
@@ -40,6 +42,11 @@ function InteractionListItem({ data: itemData, index, style }: Props) {
|
||||
? commitTimes[interaction.commits[interaction.commits.length - 1]]
|
||||
: interaction.timestamp;
|
||||
|
||||
const viewCommit = (commitIndex: number) => {
|
||||
selectTab('flame-chart');
|
||||
selectCommitIndex(commitIndex);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
@@ -68,6 +75,7 @@ function InteractionListItem({ data: itemData, index, style }: Props) {
|
||||
<div
|
||||
className={styles.CommitBox}
|
||||
key={commitIndex}
|
||||
onClick={() => viewCommit(commitIndex)}
|
||||
style={{
|
||||
backgroundColor: getGradientColor(
|
||||
Math.min(
|
||||
|
||||
@@ -12,6 +12,7 @@ import { scale } from './utils';
|
||||
import styles from './Interactions.css';
|
||||
|
||||
import type { ChartData } from './InteractionsChartBuilder';
|
||||
import type { TabID } from './ProfilerContext';
|
||||
import type { InteractionWithCommits, ProfilingSummary } from './types';
|
||||
|
||||
export type ItemData = {|
|
||||
@@ -21,7 +22,9 @@ export type ItemData = {|
|
||||
profilingSummary: ProfilingSummary,
|
||||
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(_: {||}) {
|
||||
@@ -40,6 +43,8 @@ function Interactions({ height, width }: {| height: number, width: number |}) {
|
||||
rootID,
|
||||
selectedInteractionID,
|
||||
selectInteraction,
|
||||
selectCommitIndex,
|
||||
selectTab,
|
||||
} = useContext(ProfilerContext);
|
||||
const { profilingCache } = useContext(StoreContext);
|
||||
|
||||
@@ -71,14 +76,18 @@ function Interactions({ height, width }: {| height: number, width: number |}) {
|
||||
profilingSummary,
|
||||
scaleX: scale(0, chartData.lastInteractionTime, 0, timelineWidth),
|
||||
selectedInteractionID,
|
||||
selectCommitIndex,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
};
|
||||
}, [
|
||||
chartData,
|
||||
interactions,
|
||||
profilingSummary,
|
||||
selectedInteractionID,
|
||||
selectCommitIndex,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
width,
|
||||
]);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ type Context = {|
|
||||
// This value is controlled by the commit selector UI in the Profiler toolbar.
|
||||
// It impacts the flame graph and ranked charts.
|
||||
selectedCommitIndex: number | null,
|
||||
setSelectedCommitIndex: (value: number | null) => void,
|
||||
selectCommitIndex: (value: number | null) => void,
|
||||
|
||||
// Which fiber is currently selected in the Ranked or Flamegraph charts?
|
||||
selectedFiberID: number | null,
|
||||
@@ -125,7 +125,7 @@ function ProfilerContextController({ children }: Props) {
|
||||
0
|
||||
);
|
||||
|
||||
const [selectedCommitIndex, setSelectedCommitIndex] = useState<number | null>(
|
||||
const [selectedCommitIndex, selectCommitIndex] = useState<number | null>(
|
||||
null
|
||||
);
|
||||
const [selectedTabID, selectTab] = useState<TabID>('flame-chart');
|
||||
@@ -137,7 +137,7 @@ function ProfilerContextController({ children }: Props) {
|
||||
if (isProfiling) {
|
||||
batchedUpdates(() => {
|
||||
if (selectedCommitIndex !== null) {
|
||||
setSelectedCommitIndex(null);
|
||||
selectCommitIndex(null);
|
||||
}
|
||||
if (selectedFiberID !== null) {
|
||||
selectFiber(null);
|
||||
@@ -168,7 +168,7 @@ function ProfilerContextController({ children }: Props) {
|
||||
setMinCommitDuration,
|
||||
|
||||
selectedCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
|
||||
selectedFiberID,
|
||||
selectFiber,
|
||||
@@ -195,7 +195,7 @@ function ProfilerContextController({ children }: Props) {
|
||||
setMinCommitDuration,
|
||||
|
||||
selectedCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
|
||||
selectedFiberID,
|
||||
selectFiber,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
.Content {
|
||||
padding: 0.5rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.List,
|
||||
@@ -20,14 +21,20 @@
|
||||
}
|
||||
|
||||
.InteractionList {
|
||||
padding: 0.5rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.ListItem,
|
||||
.InteractionListItem {
|
||||
.ListItem {
|
||||
margin: 0 0 0.5rem;
|
||||
}
|
||||
|
||||
.InteractionListItem {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.InteractionListItem:hover {
|
||||
background-color: var(--color-hover-background);
|
||||
}
|
||||
|
||||
.Label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -10,9 +10,13 @@ import styles from './SidebarCommitInfo.css';
|
||||
export type Props = {||};
|
||||
|
||||
export default function SidebarCommitInfo(_: Props) {
|
||||
const { selectedCommitIndex, rendererID, rootID } = useContext(
|
||||
ProfilerContext
|
||||
);
|
||||
const {
|
||||
selectedCommitIndex,
|
||||
rendererID,
|
||||
rootID,
|
||||
selectInteraction,
|
||||
selectTab,
|
||||
} = useContext(ProfilerContext);
|
||||
|
||||
const { profilingCache } = useContext(StoreContext);
|
||||
|
||||
@@ -33,6 +37,11 @@ export default function SidebarCommitInfo(_: Props) {
|
||||
rootID: ((rootID: any): number),
|
||||
});
|
||||
|
||||
const viewInteraction = interaction => {
|
||||
selectTab('interactions');
|
||||
selectInteraction(interaction.id);
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={styles.Toolbar}>Commit information</div>
|
||||
@@ -53,14 +62,18 @@ export default function SidebarCommitInfo(_: Props) {
|
||||
ms
|
||||
</span>
|
||||
</li>
|
||||
<li className={styles.ListItem}>
|
||||
<li className={styles.InteractionList}>
|
||||
<label className={styles.Label}>Interactions</label>:
|
||||
<ul className={styles.InteractionList}>
|
||||
{interactions.length === 0 ? (
|
||||
<li className={styles.InteractionListItem}>None</li>
|
||||
) : null}
|
||||
{interactions.map((interaction, index) => (
|
||||
<li key={index} className={styles.ListItem}>
|
||||
<li
|
||||
key={index}
|
||||
className={styles.InteractionListItem}
|
||||
onClick={() => viewInteraction(interaction)}
|
||||
>
|
||||
{interaction.name}
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
.Content {
|
||||
padding: 0.5rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.Name {
|
||||
@@ -27,3 +28,16 @@
|
||||
height: 100%;
|
||||
color: var(--color-dim);
|
||||
}
|
||||
|
||||
.List {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ListItem {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
.ListItem:hover {
|
||||
background-color: var(--color-hover-background);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,13 @@ import type { InteractionWithCommits } from './types';
|
||||
export type Props = {||};
|
||||
|
||||
export default function SidebarInteractions(_: Props) {
|
||||
const { selectedInteractionID, rendererID, rootID } = useContext(
|
||||
ProfilerContext
|
||||
);
|
||||
const {
|
||||
selectedInteractionID,
|
||||
rendererID,
|
||||
rootID,
|
||||
selectCommitIndex,
|
||||
selectTab,
|
||||
} = useContext(ProfilerContext);
|
||||
|
||||
const { profilingCache } = useContext(StoreContext);
|
||||
|
||||
@@ -37,15 +41,24 @@ export default function SidebarInteractions(_: Props) {
|
||||
interaction => interaction.id === selectedInteractionID
|
||||
): any): InteractionWithCommits);
|
||||
|
||||
const viewCommit = (commitIndex: number) => {
|
||||
selectTab('flame-chart');
|
||||
selectCommitIndex(commitIndex);
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={styles.Toolbar}>
|
||||
<div className={styles.Name}>{interaction.name}</div>
|
||||
</div>
|
||||
<div className={styles.Content}>
|
||||
<ul>
|
||||
<ul className={styles.List}>
|
||||
{interaction.commits.map(commitIndex => (
|
||||
<li key={commitIndex}>
|
||||
<li
|
||||
key={commitIndex}
|
||||
className={styles.ListItem}
|
||||
onClick={() => viewCommit(commitIndex)}
|
||||
>
|
||||
timestamp: {formatTime(commitTimes[commitIndex])}s
|
||||
<br />
|
||||
duration: {formatDuration(commitDurations[commitIndex])}ms
|
||||
|
||||
@@ -20,7 +20,7 @@ export type ItemData = {|
|
||||
maxDuration: number,
|
||||
selectedCommitIndex: number | null,
|
||||
selectedFilteredCommitIndex: number | null,
|
||||
setSelectedCommitIndex: (index: number) => void,
|
||||
selectCommitIndex: (index: number) => void,
|
||||
|};
|
||||
|
||||
type Props = {|
|
||||
@@ -29,7 +29,7 @@ type Props = {|
|
||||
filteredCommitIndices: Array<number>,
|
||||
selectedCommitIndex: number | null,
|
||||
selectedFilteredCommitIndex: number | null,
|
||||
setSelectedCommitIndex: (index: number) => void,
|
||||
selectCommitIndex: (index: number) => void,
|
||||
|};
|
||||
|
||||
export default function SnapshotCommitList({
|
||||
@@ -38,7 +38,7 @@ export default function SnapshotCommitList({
|
||||
filteredCommitIndices,
|
||||
selectedCommitIndex,
|
||||
selectedFilteredCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
}: Props) {
|
||||
return (
|
||||
<AutoSizer>
|
||||
@@ -50,7 +50,7 @@ export default function SnapshotCommitList({
|
||||
filteredCommitIndices={filteredCommitIndices}
|
||||
selectedCommitIndex={selectedCommitIndex}
|
||||
selectedFilteredCommitIndex={selectedFilteredCommitIndex}
|
||||
setSelectedCommitIndex={setSelectedCommitIndex}
|
||||
selectCommitIndex={selectCommitIndex}
|
||||
width={width}
|
||||
/>
|
||||
)}
|
||||
@@ -65,7 +65,7 @@ type ListProps = {|
|
||||
filteredCommitIndices: Array<number>,
|
||||
selectedCommitIndex: number | null,
|
||||
selectedFilteredCommitIndex: number | null,
|
||||
setSelectedCommitIndex: (index: number) => void,
|
||||
selectCommitIndex: (index: number) => void,
|
||||
width: number,
|
||||
|};
|
||||
|
||||
@@ -76,7 +76,7 @@ function List({
|
||||
height,
|
||||
filteredCommitIndices,
|
||||
selectedFilteredCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
width,
|
||||
}: ListProps) {
|
||||
const listRef = useRef<FixedSizeList<ItemData> | null>(null);
|
||||
@@ -139,7 +139,7 @@ function List({
|
||||
maxDuration,
|
||||
selectedCommitIndex,
|
||||
selectedFilteredCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
}),
|
||||
[
|
||||
commitDurations,
|
||||
@@ -149,7 +149,7 @@ function List({
|
||||
maxDuration,
|
||||
selectedCommitIndex,
|
||||
selectedFilteredCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ function SnapshotCommitListItem({ data: itemData, index, style }: Props) {
|
||||
isMouseDown,
|
||||
maxDuration,
|
||||
selectedCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
} = itemData;
|
||||
|
||||
index = filteredCommitIndices[index];
|
||||
@@ -30,9 +30,9 @@ function SnapshotCommitListItem({ data: itemData, index, style }: Props) {
|
||||
const commitDuration = commitDurations[index];
|
||||
const commitTime = commitTimes[index];
|
||||
|
||||
const handleClick = useCallback(() => setSelectedCommitIndex(index), [
|
||||
const handleClick = useCallback(() => selectCommitIndex(index), [
|
||||
index,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
]);
|
||||
|
||||
// Guard against commits with duration 0
|
||||
|
||||
@@ -21,7 +21,7 @@ export default function SnapshotSelector(_: Props) {
|
||||
rendererID,
|
||||
rootID,
|
||||
selectedCommitIndex,
|
||||
setSelectedCommitIndex,
|
||||
selectCommitIndex,
|
||||
} = useContext(ProfilerContext);
|
||||
|
||||
const { profilingCache } = useContext(StoreContext);
|
||||
@@ -62,12 +62,10 @@ export default function SnapshotSelector(_: Props) {
|
||||
// Maybe this component should pass filteredCommitIndices up?
|
||||
if (selectedFilteredCommitIndex === null) {
|
||||
if (numFilteredCommits > 0) {
|
||||
setSelectedCommitIndex(0);
|
||||
selectCommitIndex(0);
|
||||
}
|
||||
} else if (selectedFilteredCommitIndex >= numFilteredCommits) {
|
||||
setSelectedCommitIndex(
|
||||
numFilteredCommits === 0 ? null : numFilteredCommits - 1
|
||||
);
|
||||
selectCommitIndex(numFilteredCommits === 0 ? null : numFilteredCommits - 1);
|
||||
}
|
||||
|
||||
let label = null;
|
||||
@@ -86,23 +84,15 @@ export default function SnapshotSelector(_: Props) {
|
||||
((selectedFilteredCommitIndex: any): number) + 1,
|
||||
filteredCommitIndices.length - 1
|
||||
);
|
||||
setSelectedCommitIndex(filteredCommitIndices[nextCommitIndex]);
|
||||
}, [
|
||||
selectedFilteredCommitIndex,
|
||||
filteredCommitIndices,
|
||||
setSelectedCommitIndex,
|
||||
]);
|
||||
selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
|
||||
}, [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex]);
|
||||
const viewPrevCommit = useCallback(() => {
|
||||
const nextCommitIndex = Math.max(
|
||||
((selectedFilteredCommitIndex: any): number) - 1,
|
||||
0
|
||||
);
|
||||
setSelectedCommitIndex(filteredCommitIndices[nextCommitIndex]);
|
||||
}, [
|
||||
selectedFilteredCommitIndex,
|
||||
filteredCommitIndices,
|
||||
setSelectedCommitIndex,
|
||||
]);
|
||||
selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
|
||||
}, [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex]);
|
||||
|
||||
if (rendererID === null || rootID === null) {
|
||||
return null;
|
||||
@@ -136,7 +126,7 @@ export default function SnapshotSelector(_: Props) {
|
||||
filteredCommitIndices={filteredCommitIndices}
|
||||
selectedCommitIndex={selectedCommitIndex}
|
||||
selectedFilteredCommitIndex={selectedFilteredCommitIndex}
|
||||
setSelectedCommitIndex={setSelectedCommitIndex}
|
||||
selectCommitIndex={selectCommitIndex}
|
||||
/>
|
||||
)}
|
||||
{numFilteredCommits === 0 && (
|
||||
|
||||
Reference in New Issue
Block a user