@samitouri / QOS-React / commits / afba752034

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 && (