Skip to content

Commit 275a2dd

Browse files
author
Brian Vaughn
committed
Add native events to the profiler
1 parent c76e4db commit 275a2dd

File tree

11 files changed

+632
-279
lines changed

11 files changed

+632
-279
lines changed

packages/react-devtools-scheduling-profiler/src/CanvasPage.js

+47-12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
} from './view-base';
4545
import {
4646
FlamechartView,
47+
NativeEventsView,
4748
ReactEventsView,
4849
ReactMeasuresView,
4950
TimeAxisMarkersView,
@@ -126,6 +127,7 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
126127

127128
const surfaceRef = useRef(new Surface());
128129
const userTimingMarksViewRef = useRef(null);
130+
const nativeEventsViewRef = useRef(null);
129131
const reactEventsViewRef = useRef(null);
130132
const reactMeasuresViewRef = useRef(null);
131133
const flamechartViewRef = useRef(null);
@@ -176,6 +178,10 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
176178
topContentStack.addSubview(userTimingMarksView);
177179
}
178180

181+
const nativeEventsView = new NativeEventsView(surface, defaultFrame, data);
182+
nativeEventsViewRef.current = nativeEventsView;
183+
topContentStack.addSubview(nativeEventsView);
184+
179185
const reactEventsView = new ReactEventsView(surface, defaultFrame, data);
180186
reactEventsViewRef.current = reactEventsView;
181187
topContentStack.addSubview(reactEventsView);
@@ -299,7 +305,24 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
299305
if (!hoveredEvent || hoveredEvent.userTimingMark !== userTimingMark) {
300306
setHoveredEvent({
301307
userTimingMark,
302-
event: null,
308+
nativeEvent: null,
309+
reactEvent: null,
310+
flamechartStackFrame: null,
311+
measure: null,
312+
data,
313+
});
314+
}
315+
};
316+
}
317+
318+
const {current: nativeEventsView} = nativeEventsViewRef;
319+
if (nativeEventsView) {
320+
nativeEventsView.onHover = nativeEvent => {
321+
if (!hoveredEvent || hoveredEvent.nativeEvent !== nativeEvent) {
322+
setHoveredEvent({
323+
userTimingMark: null,
324+
nativeEvent,
325+
reactEvent: null,
303326
flamechartStackFrame: null,
304327
measure: null,
305328
data,
@@ -310,11 +333,12 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
310333

311334
const {current: reactEventsView} = reactEventsViewRef;
312335
if (reactEventsView) {
313-
reactEventsView.onHover = event => {
314-
if (!hoveredEvent || hoveredEvent.event !== event) {
336+
reactEventsView.onHover = reactEvent => {
337+
if (!hoveredEvent || hoveredEvent.reactEvent !== reactEvent) {
315338
setHoveredEvent({
316339
userTimingMark: null,
317-
event,
340+
nativeEvent: null,
341+
reactEvent,
318342
flamechartStackFrame: null,
319343
measure: null,
320344
data,
@@ -329,7 +353,8 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
329353
if (!hoveredEvent || hoveredEvent.measure !== measure) {
330354
setHoveredEvent({
331355
userTimingMark: null,
332-
event: null,
356+
nativeEvent: null,
357+
reactEvent: null,
333358
flamechartStackFrame: null,
334359
measure,
335360
data,
@@ -347,7 +372,8 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
347372
) {
348373
setHoveredEvent({
349374
userTimingMark: null,
350-
event: null,
375+
nativeEvent: null,
376+
reactEvent: null,
351377
flamechartStackFrame,
352378
measure: null,
353379
data,
@@ -368,9 +394,18 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
368394
);
369395
}
370396

397+
const {current: nativeEventsView} = nativeEventsViewRef;
398+
if (nativeEventsView) {
399+
nativeEventsView.setHoveredEvent(
400+
hoveredEvent ? hoveredEvent.nativeEvent : null,
401+
);
402+
}
403+
371404
const {current: reactEventsView} = reactEventsViewRef;
372405
if (reactEventsView) {
373-
reactEventsView.setHoveredEvent(hoveredEvent ? hoveredEvent.event : null);
406+
reactEventsView.setHoveredEvent(
407+
hoveredEvent ? hoveredEvent.reactEvent : null,
408+
);
374409
}
375410

376411
const {current: reactMeasuresView} = reactMeasuresViewRef;
@@ -402,22 +437,22 @@ function AutoSizedCanvas({data, height, width}: AutoSizedCanvasProps) {
402437
return null;
403438
}
404439
const {
405-
event,
440+
reactEvent,
406441
flamechartStackFrame,
407442
measure,
408443
} = contextData.hoveredEvent;
409444
return (
410445
<Fragment>
411-
{event !== null && (
446+
{reactEvent !== null && (
412447
<ContextMenuItem
413-
onClick={() => copy(event.componentName)}
448+
onClick={() => copy(reactEvent.componentName)}
414449
title="Copy component name">
415450
Copy component name
416451
</ContextMenuItem>
417452
)}
418-
{event !== null && event.componentStack && (
453+
{reactEvent !== null && reactEvent.componentStack && (
419454
<ContextMenuItem
420-
onClick={() => copy(event.componentStack)}
455+
onClick={() => copy(reactEvent.componentStack)}
421456
title="Copy component stack">
422457
Copy component stack
423458
</ContextMenuItem>

packages/react-devtools-scheduling-profiler/src/EventTooltip.css

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
.DetailsGridLabel {
3030
color: var(--color-dim);
3131
text-align: right;
32+
white-space: nowrap;
3233
}
3334

3435
.DetailsGridURL {
@@ -45,7 +46,7 @@
4546
.ComponentName {
4647
font-weight: bold;
4748
word-break: break-word;
48-
margin-right: 0.4rem;
49+
margin-right: 0.25rem;
4950
}
5051

5152
.ComponentStack {

packages/react-devtools-scheduling-profiler/src/EventTooltip.js

+48-11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import type {Point} from './view-base';
1111
import type {
1212
FlamechartStackFrame,
13+
NativeEvent,
1314
ReactEvent,
1415
ReactHoverContextInfo,
1516
ReactMeasure,
@@ -47,8 +48,8 @@ function trimmedString(string: string, length: number): string {
4748
return string;
4849
}
4950

50-
function getReactEventLabel(type): string | null {
51-
switch (type) {
51+
function getReactEventLabel(event: ReactEvent): string | null {
52+
switch (event.type) {
5253
case 'schedule-render':
5354
return 'render scheduled';
5455
case 'schedule-state-update':
@@ -111,10 +112,22 @@ export default function EventTooltip({data, hoveredEvent, origin}: Props) {
111112
return null;
112113
}
113114

114-
const {event, measure, flamechartStackFrame, userTimingMark} = hoveredEvent;
115+
const {
116+
nativeEvent,
117+
reactEvent,
118+
measure,
119+
flamechartStackFrame,
120+
userTimingMark,
121+
} = hoveredEvent;
115122

116-
if (event !== null) {
117-
return <TooltipReactEvent event={event} tooltipRef={tooltipRef} />;
123+
if (nativeEvent !== null) {
124+
return (
125+
<TooltipNativeEvent nativeEvent={nativeEvent} tooltipRef={tooltipRef} />
126+
);
127+
} else if (reactEvent !== null) {
128+
return (
129+
<TooltipReactEvent reactEvent={reactEvent} tooltipRef={tooltipRef} />
130+
);
118131
} else if (measure !== null) {
119132
return (
120133
<TooltipReactMeasure
@@ -189,23 +202,47 @@ const TooltipFlamechartNode = ({
189202
);
190203
};
191204

205+
const TooltipNativeEvent = ({
206+
nativeEvent,
207+
tooltipRef,
208+
}: {
209+
nativeEvent: NativeEvent,
210+
tooltipRef: Return<typeof useRef>,
211+
}) => {
212+
const {duration, timestamp, type} = nativeEvent;
213+
214+
return (
215+
<div className={styles.Tooltip} ref={tooltipRef}>
216+
<span className={styles.ComponentName}>{trimmedString(type, 768)}</span>
217+
event
218+
<div className={styles.Divider} />
219+
<div className={styles.DetailsGrid}>
220+
<div className={styles.DetailsGridLabel}>Timestamp:</div>
221+
<div>{formatTimestamp(timestamp)}</div>
222+
<div className={styles.DetailsGridLabel}>Duration:</div>
223+
<div>{formatDuration(duration)}</div>
224+
</div>
225+
</div>
226+
);
227+
};
228+
192229
const TooltipReactEvent = ({
193-
event,
230+
reactEvent,
194231
tooltipRef,
195232
}: {
196-
event: ReactEvent,
233+
reactEvent: ReactEvent,
197234
tooltipRef: Return<typeof useRef>,
198235
}) => {
199-
const label = getReactEventLabel(event.type);
200-
const color = getReactEventColor(event);
236+
const label = getReactEventLabel(reactEvent);
237+
const color = getReactEventColor(reactEvent);
201238
if (!label || !color) {
202239
if (__DEV__) {
203-
console.warn('Unexpected event type "%s"', event.type);
240+
console.warn('Unexpected reactEvent type "%s"', reactEvent.type);
204241
}
205242
return null;
206243
}
207244

208-
const {componentName, componentStack, timestamp} = event;
245+
const {componentName, componentStack, timestamp} = reactEvent;
209246

210247
return (
211248
<div className={styles.Tooltip} ref={tooltipRef}>

0 commit comments

Comments
 (0)