Skip to content

Commit ba9f471

Browse files
Brian Vaughnkoto
authored andcommitted
Improve DevTools Profiler commit-selector UX (facebook#20943)
* Improve DevTools Profiler commit-selector UX 1. Use natural log of durations (rather than linear) when calculating bar height. This reduces the impact of one (or few) outlier times on more common smaller durations. (Continue to use linear for bar color though.) 2. Decrease the minimum bar height to make the differences in height more noticeable. 3. Add a background hover highlight to increase contrast. 4. Add hover tooltip with commit duration and timestamp.
1 parent e3d029e commit ba9f471

File tree

5 files changed

+60
-19
lines changed

5 files changed

+60
-19
lines changed

packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import AutoSizer from 'react-virtualized-auto-sizer';
1313
import {FixedSizeList} from 'react-window';
1414
import SnapshotCommitListItem from './SnapshotCommitListItem';
1515
import {minBarWidth} from './constants';
16+
import {formatDuration, formatTime} from './utils';
17+
import Tooltip from './Tooltip';
1618

1719
import styles from './SnapshotCommitList.css';
1820

@@ -24,6 +26,7 @@ export type ItemData = {|
2426
selectedCommitIndex: number | null,
2527
selectedFilteredCommitIndex: number | null,
2628
selectCommitIndex: (index: number) => void,
29+
setHoveredCommitIndex: (index: number) => void,
2730
startCommitDrag: (newDragState: DragState) => void,
2831
|};
2932

@@ -166,6 +169,10 @@ function List({
166169
}
167170
}, [dragState]);
168171

172+
const [hoveredCommitIndex, setHoveredCommitIndex] = useState<number | null>(
173+
null,
174+
);
175+
169176
// Pass required contextual data down to the ListItem renderer.
170177
const itemData = useMemo<ItemData>(
171178
() => ({
@@ -176,6 +183,7 @@ function List({
176183
selectedCommitIndex,
177184
selectedFilteredCommitIndex,
178185
selectCommitIndex,
186+
setHoveredCommitIndex,
179187
startCommitDrag: setDragState,
180188
}),
181189
[
@@ -186,22 +194,37 @@ function List({
186194
selectedCommitIndex,
187195
selectedFilteredCommitIndex,
188196
selectCommitIndex,
197+
setHoveredCommitIndex,
189198
],
190199
);
191200

201+
let tooltipLabel = null;
202+
if (hoveredCommitIndex !== null) {
203+
const commitDuration = commitDurations[hoveredCommitIndex];
204+
const commitTime = commitTimes[hoveredCommitIndex];
205+
tooltipLabel = `${formatDuration(commitDuration)}ms at ${formatTime(
206+
commitTime,
207+
)}s`;
208+
}
209+
192210
return (
193-
<div ref={divRef} style={{height, width}}>
194-
<FixedSizeList
195-
className={styles.List}
196-
layout="horizontal"
197-
height={height}
198-
itemCount={filteredCommitIndices.length}
199-
itemData={itemData}
200-
itemSize={itemSize}
201-
ref={(listRef: any) /* Flow bug? */}
202-
width={width}>
203-
{SnapshotCommitListItem}
204-
</FixedSizeList>
205-
</div>
211+
<Tooltip label={tooltipLabel}>
212+
<div
213+
ref={divRef}
214+
style={{height, width}}
215+
onMouseLeave={() => setHoveredCommitIndex(null)}>
216+
<FixedSizeList
217+
className={styles.List}
218+
layout="horizontal"
219+
height={height}
220+
itemCount={filteredCommitIndices.length}
221+
itemData={itemData}
222+
itemSize={itemSize}
223+
ref={(listRef: any) /* Flow bug? */}
224+
width={width}>
225+
{SnapshotCommitListItem}
226+
</FixedSizeList>
227+
</div>
228+
</Tooltip>
206229
);
207230
}

packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.css

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
display: flex;
88
align-items: flex-end;
99
}
10+
.Outer:hover {
11+
background-color: var(--color-background);
12+
}
1013

1114
.Inner {
1215
width: 100%;
13-
min-height: 5px;
16+
min-height: 2px;
1417
background-color: var(--color-commit-did-not-render-fill);
1518
color: var(--color-commit-did-not-render-fill-text);
1619
}

packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
3131
maxDuration,
3232
selectedCommitIndex,
3333
selectCommitIndex,
34+
setHoveredCommitIndex,
3435
startCommitDrag,
3536
} = itemData;
3637

@@ -39,9 +40,21 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
3940
const commitDuration = commitDurations[index];
4041
const commitTime = commitTimes[index];
4142

42-
// Guard against commits with duration 0
43-
const percentage =
43+
// Use natural log for bar height.
44+
// This prevents one (or a few) outliers from squishing the majority of other commits.
45+
// So rather than e.g. _█_ we get something more like e.g. ▄█_
46+
const heightScale =
47+
Math.min(
48+
1,
49+
Math.max(0, Math.log(commitDuration) / Math.log(maxDuration)),
50+
) || 0;
51+
52+
// Use a linear scale for color.
53+
// This gives some visual contrast between cheaper and more expensive commits
54+
// and somewhat compensates for the log scale height.
55+
const colorScale =
4456
Math.min(1, Math.max(0, commitDuration / maxDuration)) || 0;
57+
4558
const isSelected = selectedCommitIndex === index;
4659

4760
// Leave a 1px gap between snapshots
@@ -62,6 +75,7 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
6275
<div
6376
className={styles.Outer}
6477
onMouseDown={handleMouseDown}
78+
onMouseEnter={() => setHoveredCommitIndex(index)}
6579
style={{
6680
...style,
6781
width,
@@ -75,9 +89,9 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
7589
<div
7690
className={styles.Inner}
7791
style={{
78-
height: `${Math.round(percentage * 100)}%`,
92+
height: `${Math.round(heightScale * 100)}%`,
7993
backgroundColor:
80-
percentage > 0 ? getGradientColor(percentage) : undefined,
94+
commitDuration > 0 ? getGradientColor(colorScale) : undefined,
8195
}}
8296
/>
8397
</div>

packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotSelector.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
height: 100%;
88
min-width: 30px;
99
margin-left: 0.25rem;
10-
overflow: hidden;
10+
overflow: visible;
1111
}
1212
.Commits:focus {
1313
outline: none;

packages/react-devtools-shared/src/devtools/views/Profiler/Tooltip.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
background-color: var(--color-tooltip-background);
1010
color: var(--color-tooltip-text);
1111
opacity: 1;
12+
white-space: nowrap;
1213
/* Make sure this is above the DevTools, which are above the Overlay */
1314
z-index: 10000002;
1415
}

0 commit comments

Comments
 (0)