Clicking commits and interactions link to each other
Brian Vaughn committed
Mar 24, 2019 at 09:46 UTC
afba752034973ae42857aec2a50ee096db6478d4
11 files changed
+116
-47
shells/dev/app/InteractionTracing/index.js
+15
@@ -21,6 +21,7 @@ export default function InteractionTracing() {
21
);
22
});
23
}, [count]);
24
+
25
const handleCascadingUpdate = useCallback(() => {
26
trace('cascade', performance.now(), () => {
27
setTimeout(
@@ -35,6 +36,19 @@ export default function InteractionTracing() {
36
});
37
}, [count]);
38
39
+ const handleMultiple = useCallback(() => {
40
+ trace('first', performance.now(), () => {
41
+ trace('second', performance.now(), () => {
42
+ setTimeout(
43
+ wrap(() => {
44
+ setCount(count + 1);
45
+ }),
46
+ count * 100
47
+ );
48
+ });
49
+ });
50
+ }, [count]);
51
+
52
useEffect(() => {
53
if (shouldCascade) {
54
setTimeout(
@@ -53,6 +67,7 @@ export default function InteractionTracing() {
67
<button onClick={handleCascadingUpdate}>
68
Cascading Update ({count}, {shouldCascade ? 'true' : 'false'})
69
</button>
70
+ <button onClick={handleMultiple}>Multiple</button>
71
</Fragment>
72
);
73
}
src/devtools/views/Profiler/InteractionListItem.js
+8
@@ -22,7 +22,9 @@ function InteractionListItem({ data: itemData, index, style }: Props) {
22
profilingSummary,
23
scaleX,
24
selectedInteractionID,
25
+ selectCommitIndex,
26
selectInteraction,
27
+ selectTab,
28
} = itemData;
29
30
const { maxCommitDuration } = chartData;
@@ -40,6 +42,11 @@ function InteractionListItem({ data: itemData, index, style }: Props) {
42
? commitTimes[interaction.commits[interaction.commits.length - 1]]
43
: interaction.timestamp;
44
45
+ const viewCommit = (commitIndex: number) => {
46
+ selectTab('flame-chart');
47
+ selectCommitIndex(commitIndex);
48
+ };
49
+
50
return (
51
<div
52
className={
@@ -68,6 +75,7 @@ function InteractionListItem({ data: itemData, index, style }: Props) {
75
<div
76
className={styles.CommitBox}
77
key={commitIndex}
78
+ onClick={() => viewCommit(commitIndex)}
79
style={{
80
backgroundColor: getGradientColor(
81
Math.min(
src/devtools/views/Profiler/Interactions.js
+9
@@ -12,6 +12,7 @@ import { scale } from './utils';
12
import styles from './Interactions.css';
13
14
import type { ChartData } from './InteractionsChartBuilder';
15
+import type { TabID } from './ProfilerContext';
16
import type { InteractionWithCommits, ProfilingSummary } from './types';
17
18
export type ItemData = {|
@@ -21,7 +22,9 @@ export type ItemData = {|
22
profilingSummary: ProfilingSummary,
23
scaleX: (value: number, fallbackValue: number) => number,
24
selectedInteractionID: number | null,
25
+ selectCommitIndex: (id: number | null) => void,
26
selectInteraction: (id: number | null) => void,
27
+ selectTab: (id: TabID) => void,
28
|};
29
30
export default function InteractionsAutoSizer(_: {||}) {
@@ -40,6 +43,8 @@ function Interactions({ height, width }: {| height: number, width: number |}) {
43
rootID,
44
selectedInteractionID,
45
selectInteraction,
46
+ selectCommitIndex,
47
+ selectTab,
48
} = useContext(ProfilerContext);
49
const { profilingCache } = useContext(StoreContext);
50
@@ -71,14 +76,18 @@ function Interactions({ height, width }: {| height: number, width: number |}) {
76
profilingSummary,
77
scaleX: scale(0, chartData.lastInteractionTime, 0, timelineWidth),
78
selectedInteractionID,
79
+ selectCommitIndex,
80
selectInteraction,
81
+ selectTab,
82
};
83
}, [
84
chartData,
85
interactions,
86
profilingSummary,
87
selectedInteractionID,
88
+ selectCommitIndex,
89
selectInteraction,
90
+ selectTab,
91
width,
92
]);
93
src/devtools/views/Profiler/ProfilerContext.js
+5
-5
@@ -50,7 +50,7 @@ type Context = {|
50
// This value is controlled by the commit selector UI in the Profiler toolbar.
51
// It impacts the flame graph and ranked charts.
52
selectedCommitIndex: number | null,
53
- setSelectedCommitIndex: (value: number | null) => void,
53
+ selectCommitIndex: (value: number | null) => void,
54
55
// Which fiber is currently selected in the Ranked or Flamegraph charts?
56
selectedFiberID: number | null,
@@ -125,7 +125,7 @@ function ProfilerContextController({ children }: Props) {
125
0
126
);
127
128
- const [selectedCommitIndex, setSelectedCommitIndex] = useState<number | null>(
128
+ const [selectedCommitIndex, selectCommitIndex] = useState<number | null>(
129
null
130
);
131
const [selectedTabID, selectTab] = useState<TabID>('flame-chart');
@@ -137,7 +137,7 @@ function ProfilerContextController({ children }: Props) {
137
if (isProfiling) {
138
batchedUpdates(() => {
139
if (selectedCommitIndex !== null) {
140
- setSelectedCommitIndex(null);
140
+ selectCommitIndex(null);
141
}
142
if (selectedFiberID !== null) {
143
selectFiber(null);
@@ -168,7 +168,7 @@ function ProfilerContextController({ children }: Props) {
168
setMinCommitDuration,
169
170
selectedCommitIndex,
171
- setSelectedCommitIndex,
171
+ selectCommitIndex,
172
173
selectedFiberID,
174
selectFiber,
@@ -195,7 +195,7 @@ function ProfilerContextController({ children }: Props) {
195
setMinCommitDuration,
196
197
selectedCommitIndex,
198
- setSelectedCommitIndex,
198
+ selectCommitIndex,
199
200
selectedFiberID,
201
selectFiber,
src/devtools/views/Profiler/SidebarCommitInfo.css
+10
-3
@@ -10,6 +10,7 @@
10
11
.Content {
12
padding: 0.5rem;
13
+ user-select: none;
14
}
15
16
.List,
@@ -20,14 +21,20 @@
21
}
22
23
.InteractionList {
23
- padding: 0.5rem;
24
+ padding: 0.25rem;
25
}
26
26
-.ListItem,
27
-.InteractionListItem {
27
+.ListItem {
28
margin: 0 0 0.5rem;
29
}
30
31
+.InteractionListItem {
32
+ padding: 0.25rem 0.5rem;
33
+}
34
+.InteractionListItem:hover {
35
+ background-color: var(--color-hover-background);
36
+}
37
+
38
.Label {
39
overflow: hidden;
40
text-overflow: ellipsis;
src/devtools/views/Profiler/SidebarCommitInfo.js
+18
-5
@@ -10,9 +10,13 @@ import styles from './SidebarCommitInfo.css';
10
export type Props = {||};
11
12
export default function SidebarCommitInfo(_: Props) {
13
- const { selectedCommitIndex, rendererID, rootID } = useContext(
14
- ProfilerContext
15
- );
13
+ const {
14
+ selectedCommitIndex,
15
+ rendererID,
16
+ rootID,
17
+ selectInteraction,
18
+ selectTab,
19
+ } = useContext(ProfilerContext);
20
21
const { profilingCache } = useContext(StoreContext);
22
@@ -33,6 +37,11 @@ export default function SidebarCommitInfo(_: Props) {
37
rootID: ((rootID: any): number),
38
});
39
40
+ const viewInteraction = interaction => {
41
+ selectTab('interactions');
42
+ selectInteraction(interaction.id);
43
+ };
44
+
45
return (
46
<Fragment>
47
<div className={styles.Toolbar}>Commit information</div>
@@ -53,14 +62,18 @@ export default function SidebarCommitInfo(_: Props) {
62
ms
63
</span>
64
</li>
56
- <li className={styles.ListItem}>
65
+ <li className={styles.InteractionList}>
66
<label className={styles.Label}>Interactions</label>:
67
<ul className={styles.InteractionList}>
68
{interactions.length === 0 ? (
69
<li className={styles.InteractionListItem}>None</li>
70
) : null}
71
{interactions.map((interaction, index) => (
63
- <li key={index} className={styles.ListItem}>
72
+ <li
73
+ key={index}
74
+ className={styles.InteractionListItem}
75
+ onClick={() => viewInteraction(interaction)}
76
+ >
77
{interaction.name}
78
</li>
79
))}
src/devtools/views/Profiler/SidebarInteractions.css
+14
@@ -10,6 +10,7 @@
10
11
.Content {
12
padding: 0.5rem;
13
+ user-select: none;
14
}
15
16
.Name {
@@ -27,3 +28,16 @@
28
height: 100%;
29
color: var(--color-dim);
30
}
31
+
32
+.List {
33
+ list-style: none;
34
+ margin: 0;
35
+ padding: 0;
36
+}
37
+
38
+.ListItem {
39
+ padding: 0.25rem 0.5rem;
40
+}
41
+.ListItem:hover {
42
+ background-color: var(--color-hover-background);
43
+}
src/devtools/views/Profiler/SidebarInteractions.js
+18
-5
@@ -12,9 +12,13 @@ import type { InteractionWithCommits } from './types';
12
export type Props = {||};
13
14
export default function SidebarInteractions(_: Props) {
15
- const { selectedInteractionID, rendererID, rootID } = useContext(
16
- ProfilerContext
17
- );
15
+ const {
16
+ selectedInteractionID,
17
+ rendererID,
18
+ rootID,
19
+ selectCommitIndex,
20
+ selectTab,
21
+ } = useContext(ProfilerContext);
22
23
const { profilingCache } = useContext(StoreContext);
24
@@ -37,15 +41,24 @@ export default function SidebarInteractions(_: Props) {
41
interaction => interaction.id === selectedInteractionID
42
): any): InteractionWithCommits);
43
44
+ const viewCommit = (commitIndex: number) => {
45
+ selectTab('flame-chart');
46
+ selectCommitIndex(commitIndex);
47
+ };
48
+
49
return (
50
<Fragment>
51
<div className={styles.Toolbar}>
52
<div className={styles.Name}>{interaction.name}</div>
53
</div>
54
<div className={styles.Content}>
46
- <ul>
55
+ <ul className={styles.List}>
56
{interaction.commits.map(commitIndex => (
48
- <li key={commitIndex}>
57
+ <li
58
+ key={commitIndex}
59
+ className={styles.ListItem}
60
+ onClick={() => viewCommit(commitIndex)}
61
+ >
62
timestamp: {formatTime(commitTimes[commitIndex])}s
63
<br />
64
duration: {formatDuration(commitDurations[commitIndex])}ms
src/devtools/views/Profiler/SnapshotCommitList.js
+8
-8
@@ -20,7 +20,7 @@ export type ItemData = {|
20
maxDuration: number,
21
selectedCommitIndex: number | null,
22
selectedFilteredCommitIndex: number | null,
23
- setSelectedCommitIndex: (index: number) => void,
23
+ selectCommitIndex: (index: number) => void,
24
|};
25
26
type Props = {|
@@ -29,7 +29,7 @@ type Props = {|
29
filteredCommitIndices: Array<number>,
30
selectedCommitIndex: number | null,
31
selectedFilteredCommitIndex: number | null,
32
- setSelectedCommitIndex: (index: number) => void,
32
+ selectCommitIndex: (index: number) => void,
33
|};
34
35
export default function SnapshotCommitList({
@@ -38,7 +38,7 @@ export default function SnapshotCommitList({
38
filteredCommitIndices,
39
selectedCommitIndex,
40
selectedFilteredCommitIndex,
41
- setSelectedCommitIndex,
41
+ selectCommitIndex,
42
}: Props) {
43
return (
44
<AutoSizer>
@@ -50,7 +50,7 @@ export default function SnapshotCommitList({
50
filteredCommitIndices={filteredCommitIndices}
51
selectedCommitIndex={selectedCommitIndex}
52
selectedFilteredCommitIndex={selectedFilteredCommitIndex}
53
- setSelectedCommitIndex={setSelectedCommitIndex}
53
+ selectCommitIndex={selectCommitIndex}
54
width={width}
55
/>
56
)}
@@ -65,7 +65,7 @@ type ListProps = {|
65
filteredCommitIndices: Array<number>,
66
selectedCommitIndex: number | null,
67
selectedFilteredCommitIndex: number | null,
68
- setSelectedCommitIndex: (index: number) => void,
68
+ selectCommitIndex: (index: number) => void,
69
width: number,
70
|};
71
@@ -76,7 +76,7 @@ function List({
76
height,
77
filteredCommitIndices,
78
selectedFilteredCommitIndex,
79
- setSelectedCommitIndex,
79
+ selectCommitIndex,
80
width,
81
}: ListProps) {
82
const listRef = useRef<FixedSizeList<ItemData> | null>(null);
@@ -139,7 +139,7 @@ function List({
139
maxDuration,
140
selectedCommitIndex,
141
selectedFilteredCommitIndex,
142
- setSelectedCommitIndex,
142
+ selectCommitIndex,
143
}),
144
[
145
commitDurations,
@@ -149,7 +149,7 @@ function List({
149
maxDuration,
150
selectedCommitIndex,
151
selectedFilteredCommitIndex,
152
- setSelectedCommitIndex,
152
+ selectCommitIndex,
153
]
154
);
155
src/devtools/views/Profiler/SnapshotCommitListItem.js
+3
-3
@@ -22,7 +22,7 @@ function SnapshotCommitListItem({ data: itemData, index, style }: Props) {
22
isMouseDown,
23
maxDuration,
24
selectedCommitIndex,
25
- setSelectedCommitIndex,
25
+ selectCommitIndex,
26
} = itemData;
27
28
index = filteredCommitIndices[index];
@@ -30,9 +30,9 @@ function SnapshotCommitListItem({ data: itemData, index, style }: Props) {
30
const commitDuration = commitDurations[index];
31
const commitTime = commitTimes[index];
32
33
- const handleClick = useCallback(() => setSelectedCommitIndex(index), [
33
+ const handleClick = useCallback(() => selectCommitIndex(index), [
34
index,
35
- setSelectedCommitIndex,
35
+ selectCommitIndex,
36
]);
37
38
// Guard against commits with duration 0
src/devtools/views/Profiler/SnapshotSelector.js
+8
-18
@@ -21,7 +21,7 @@ export default function SnapshotSelector(_: Props) {
21
rendererID,
22
rootID,
23
selectedCommitIndex,
24
- setSelectedCommitIndex,
24
+ selectCommitIndex,
25
} = useContext(ProfilerContext);
26
27
const { profilingCache } = useContext(StoreContext);
@@ -62,12 +62,10 @@ export default function SnapshotSelector(_: Props) {
62
// Maybe this component should pass filteredCommitIndices up?
63
if (selectedFilteredCommitIndex === null) {
64
if (numFilteredCommits > 0) {
65
- setSelectedCommitIndex(0);
65
+ selectCommitIndex(0);
66
}
67
} else if (selectedFilteredCommitIndex >= numFilteredCommits) {
68
- setSelectedCommitIndex(
69
- numFilteredCommits === 0 ? null : numFilteredCommits - 1
70
- );
68
+ selectCommitIndex(numFilteredCommits === 0 ? null : numFilteredCommits - 1);
69
}
70
71
let label = null;
@@ -86,23 +84,15 @@ export default function SnapshotSelector(_: Props) {
84
((selectedFilteredCommitIndex: any): number) + 1,
85
filteredCommitIndices.length - 1
86
);
89
- setSelectedCommitIndex(filteredCommitIndices[nextCommitIndex]);
90
- }, [
91
- selectedFilteredCommitIndex,
92
- filteredCommitIndices,
93
- setSelectedCommitIndex,
94
- ]);
87
+ selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
88
+ }, [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex]);
89
const viewPrevCommit = useCallback(() => {
90
const nextCommitIndex = Math.max(
91
((selectedFilteredCommitIndex: any): number) - 1,
92
0
93
);
100
- setSelectedCommitIndex(filteredCommitIndices[nextCommitIndex]);
101
- }, [
102
- selectedFilteredCommitIndex,
103
- filteredCommitIndices,
104
- setSelectedCommitIndex,
105
- ]);
94
+ selectCommitIndex(filteredCommitIndices[nextCommitIndex]);
95
+ }, [selectedFilteredCommitIndex, filteredCommitIndices, selectCommitIndex]);
96
97
if (rendererID === null || rootID === null) {
98
return null;
@@ -136,7 +126,7 @@ export default function SnapshotSelector(_: Props) {
126
filteredCommitIndices={filteredCommitIndices}
127
selectedCommitIndex={selectedCommitIndex}
128
selectedFilteredCommitIndex={selectedFilteredCommitIndex}
139
- setSelectedCommitIndex={setSelectedCommitIndex}
129
+ selectCommitIndex={selectCommitIndex}
130
/>
131
)}
132
{numFilteredCommits === 0 && (