Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit f8f91e4

Browse files
authored
Profiler UI/UX tweaks and bug-fixes (#1112)
* Incorporated some interactions feedback from Shirley Wu: 1. Replace interaction commit circles with squares 2. Color commits in both the main and right-side pane based on their duration (to tie into other chart views) 3. Remove click-to-select commit because this surprised Sophie and Shirley initially * Replaced simple cache with lru cache for chart data * Only scroll selected node if not already visible * Profiler radio button text is not selectable * Don't persist selected chart type between sessions * Removed hpyhen from interaction-tracking in 'learn more' note * Fixed off-by-1 toolbar height issue * Color selected commit black in interactions detail panel too * Improve UI/UX for commits with a duration of 0
1 parent 7205587 commit f8f91e4

16 files changed

+163
-165
lines changed

frontend/Node.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ class Node extends React.Component<PropsType, StateType> {
157157
ensureInView() {
158158
var node = this.props.isBottomTagSelected ? this._tail : this._head;
159159
if (node != null) {
160-
if (typeof node.scrollIntoView === 'function') {
160+
if (typeof node.scrollIntoViewIfNeeded === 'function') {
161+
node.scrollIntoViewIfNeeded();
162+
} else if (typeof node.scrollIntoView === 'function') {
161163
node.scrollIntoView({
162164
// $FlowFixMe Flow does not realize block:"nearest" is a valid option
163165
block: 'nearest',
@@ -167,6 +169,13 @@ class Node extends React.Component<PropsType, StateType> {
167169
}
168170
}
169171

172+
_setTailRef = tail => {
173+
this._tail = tail;
174+
};
175+
_setHeadRef = head => {
176+
this._head = head;
177+
};
178+
170179
render() {
171180
const {theme} = this.context;
172181
const {
@@ -251,7 +260,7 @@ class Node extends React.Component<PropsType, StateType> {
251260
}
252261
return (
253262
<div
254-
ref={h => this._head = h}
263+
ref={this._setHeadRef}
255264
style={sharedHeadStyle}
256265
{...headEvents}
257266
>
@@ -293,9 +302,9 @@ class Node extends React.Component<PropsType, StateType> {
293302
const isCollapsed = content === null || content === undefined;
294303
return (
295304
<div style={headWrapperStyle}>
296-
<div ref={h => this._head = h} style={sharedHeadStyle} {...headEvents}>
305+
<div style={sharedHeadStyle} {...headEvents}>
297306
&lt;
298-
<span style={jsxSingleLineTagStyle}>{name}</span>
307+
<span ref={this._setHeadRef} style={jsxSingleLineTagStyle}>{name}</span>
299308
{node.get('key') &&
300309
<Props key="key" props={{'key': node.get('key')}} inverted={inverted}/>
301310
}
@@ -323,7 +332,7 @@ class Node extends React.Component<PropsType, StateType> {
323332
const closeTag = (
324333
<Fragment>
325334
&lt;/
326-
<span style={jsxCloseTagStyle}>{name}</span>
335+
<span ref={this._setTailRef} style={jsxCloseTagStyle}>{name}</span>
327336
&gt;
328337
{selected && ((collapsed && !this.props.isBottomTagSelected) || this.props.isBottomTagSelected) &&
329338
<span style={dollarRStyle}>&nbsp;== $r</span>
@@ -335,7 +344,7 @@ class Node extends React.Component<PropsType, StateType> {
335344

336345
const jsxOpenTagStyle = jsxTagStyle(inverted && (!isBottomTagSelected || collapsed), nodeType, theme);
337346
const head = (
338-
<div ref={h => this._head = h} style={sharedHeadStyle} {...headEvents}>
347+
<div style={sharedHeadStyle} {...headEvents}>
339348
<span
340349
onClick={onToggleCollapse}
341350
style={{
@@ -347,7 +356,7 @@ class Node extends React.Component<PropsType, StateType> {
347356
{collapsed ? '▶' : '▼'}
348357
</span>
349358
&lt;
350-
<span style={jsxOpenTagStyle}>{name}</span>
359+
<span ref={this._setHeadRef} style={jsxOpenTagStyle}>{name}</span>
351360
{node.get('key') &&
352361
<Props key="key" props={{'key': node.get('key')}} inverted={headInverted}/>
353362
}
@@ -394,7 +403,7 @@ class Node extends React.Component<PropsType, StateType> {
394403
}}>
395404
{children.map(id => <WrappedNode key={id} depth={depth + 1} id={id}/>)}
396405
</div>
397-
<div ref={t => this._tail = t} style={tailStyleActual} {...tailEvents}>
406+
<div style={tailStyleActual} {...tailEvents}>
398407
{closeTag}
399408
</div>
400409
</div>

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"jest": "22.1.4",
2525
"json-loader": "0.5.4",
2626
"log-update": "^2.0.0",
27+
"lru-cache": "^4.1.3",
2728
"memoize-one": "^3.1.1",
2829
"node-libs-browser": "0.5.3",
2930
"nullthrows": "^1.0.0",

plugins/Profiler/ProfilerStore.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import type {ChartType, Interaction, RootProfilerData, Snapshot} from './Profile
1616
const {List} = require('immutable');
1717
const {EventEmitter} = require('events');
1818
const {get, set} = require('../../utils/storage');
19+
const LRU = require('lru-cache');
1920

20-
const LOCAL_STORAGE_CHART_TYPE_KEY = 'profiler:selectedChartType';
2121
const LOCAL_STORAGE_COMMIT_THRESHOLD = 'profiler:commitThreshold';
2222
const LOCAL_STORAGE_HIDE_COMMITS_BELOW_THRESHOLD = 'profiler:hideCommitsBelowThreshold';
2323
const LOCAL_STORAGE_SHOW_NATIVE_NODES_KEY = 'profiler:showNativeNodes';
@@ -26,15 +26,15 @@ class ProfilerStore extends EventEmitter {
2626
_bridge: Bridge;
2727
_mainStore: Object;
2828

29-
cachedData = {};
29+
cachedData = LRU(50); // Evict items from the cache after this number
3030
commitThreshold: number = ((get(LOCAL_STORAGE_COMMIT_THRESHOLD, 0): any): number);
3131
hideCommitsBelowThreshold: boolean = ((get(LOCAL_STORAGE_HIDE_COMMITS_BELOW_THRESHOLD, false): any): boolean);
3232
isRecording: boolean = false;
3333
isSettingsPanelActive: boolean = false;
3434
processedInteractions: {[id: string]: Interaction} = {};
3535
rootsToProfilerData: Map<string, RootProfilerData> = new Map();
3636
roots: List = new List();
37-
selectedChartType: ChartType = ((get(LOCAL_STORAGE_CHART_TYPE_KEY, 'flamegraph'): any): ChartType);
37+
selectedChartType: ChartType = 'flamegraph';
3838
selectedRoot: string | null = null;
3939
showNativeNodes: boolean = ((get(LOCAL_STORAGE_SHOW_NATIVE_NODES_KEY, false): any): boolean);
4040

@@ -54,26 +54,26 @@ class ProfilerStore extends EventEmitter {
5454
}
5555

5656
cacheDataForSnapshot(snapshotIndex: number, snapshotRootID: string, key: string, data: any): void {
57-
this.cachedData[`${snapshotIndex}-${snapshotRootID}-${key}`] = data;
57+
this.cachedData.set(`${snapshotIndex}-${snapshotRootID}-${key}`, data);
5858
}
5959

6060
cacheInteractionData(rootID: string, data: any): void {
61-
this.cachedData[`${rootID}-interactions`] = data;
61+
this.cachedData.set(`${rootID}-interactions`, data);
6262
}
6363

6464
clearSnapshots = () => {
65-
this.cachedData = {};
65+
this.cachedData.reset();
6666
this.processedInteractions = {};
6767
this.rootsToProfilerData = new Map();
6868
this.emit('profilerData', this.rootsToProfilerData);
6969
};
7070

7171
getCachedDataForSnapshot(snapshotIndex: number, snapshotRootID: string, key: string): any {
72-
return this.cachedData[`${snapshotIndex}-${snapshotRootID}-${key}`] || null;
72+
return this.cachedData.get(`${snapshotIndex}-${snapshotRootID}-${key}`) || null;
7373
}
7474

7575
getCachedInteractionData(rootID: string): any {
76-
return this.cachedData[`${rootID}-interactions`] || null;
76+
return this.cachedData.get(`${rootID}-interactions`) || null;
7777
}
7878

7979
processInteraction(interaction: Interaction): Interaction {
@@ -117,7 +117,6 @@ class ProfilerStore extends EventEmitter {
117117
setSelectedChartType(selectedChartType: ChartType) {
118118
this.selectedChartType = selectedChartType;
119119
this.emit('selectedChartType', selectedChartType);
120-
set(LOCAL_STORAGE_CHART_TYPE_KEY, selectedChartType);
121120
}
122121

123122
setShowNativeNodes(showNativeNodes: boolean) {

plugins/Profiler/views/FiberRenderDurations.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type ChartData = {|
3636
type ItemData = {|
3737
height: number,
3838
nodes: Array<Node>,
39-
scaleY: (value: number) => number,
39+
scaleY: (value: number, fallbackValue: number) => number,
4040
selectedSnapshot: Snapshot,
4141
selectSnapshot: SelectSnapshot,
4242
stopInspecting: Function,
@@ -179,7 +179,7 @@ class ListItem extends PureComponent<any, void> {
179179
const { height, nodes, scaleY, selectedSnapshot, selectSnapshot, stopInspecting, theme } = itemData;
180180

181181
const node = nodes[index];
182-
const safeHeight = Math.max(minBarHeight, scaleY(node.value));
182+
const safeHeight = Math.max(minBarHeight, scaleY(node.value, minBarHeight));
183183

184184
// List items are absolutely positioned using the CSS "left" attribute.
185185
// The "top" value will always be 0.

0 commit comments

Comments
 (0)