Skip to content

Commit 05b61f8

Browse files
authored
Add Gesture Track in Performance Tab (#34546)
1 parent e0c421a commit 05b61f8

File tree

4 files changed

+328
-13
lines changed

4 files changed

+328
-13
lines changed

packages/react-reconciler/src/ReactFiberLane.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
retryLaneExpirationMs,
2929
disableLegacyMode,
3030
enableDefaultTransitionIndicator,
31+
enableGestureTransition,
3132
} from 'shared/ReactFeatureFlags';
3233
import {isDevToolsPresent} from './ReactFiberDevToolsHook';
3334
import {clz32} from './clz32';
@@ -710,6 +711,9 @@ export function isTransitionLane(lane: Lane): boolean {
710711
}
711712

712713
export function isGestureRender(lanes: Lanes): boolean {
714+
if (!enableGestureTransition) {
715+
return false;
716+
}
713717
// This should render only the one lane.
714718
return lanes === GestureLane;
715719
}
@@ -1271,11 +1275,13 @@ export function getGroupNameOfHighestPriorityLane(lanes: Lanes): string {
12711275
InputContinuousHydrationLane |
12721276
InputContinuousLane |
12731277
DefaultHydrationLane |
1274-
DefaultLane |
1275-
GestureLane)
1278+
DefaultLane)
12761279
) {
12771280
return 'Blocking';
12781281
}
1282+
if (lanes & GestureLane) {
1283+
return 'Gesture';
1284+
}
12791285
if (lanes & (TransitionHydrationLane | TransitionLanes)) {
12801286
return 'Transition';
12811287
}

packages/react-reconciler/src/ReactFiberPerformanceTrack.js

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ import {
3333
addObjectDiffToProperties,
3434
} from 'shared/ReactPerformanceTrackProperties';
3535

36-
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
36+
import {
37+
enableProfilerTimer,
38+
enableGestureTransition,
39+
} from 'shared/ReactFeatureFlags';
3740

3841
const supportsUserTiming =
3942
enableProfilerTimer &&
@@ -68,6 +71,16 @@ export function markAllLanesInOrder() {
6871
LANES_TRACK_GROUP,
6972
'primary-light',
7073
);
74+
if (enableGestureTransition) {
75+
console.timeStamp(
76+
'Gesture Track',
77+
0.003,
78+
0.003,
79+
'Gesture',
80+
LANES_TRACK_GROUP,
81+
'primary-light',
82+
);
83+
}
7184
console.timeStamp(
7285
'Transition Track',
7386
0.003,
@@ -739,6 +752,145 @@ export function logBlockingStart(
739752
}
740753
}
741754

755+
export function logGestureStart(
756+
startTime: number,
757+
updateTime: number,
758+
eventTime: number,
759+
eventType: null | string,
760+
eventIsRepeat: boolean,
761+
isPingedUpdate: boolean,
762+
renderStartTime: number,
763+
debugTask: null | ConsoleTask, // DEV-only
764+
updateMethodName: null | string,
765+
updateComponentName: null | string,
766+
): void {
767+
if (supportsUserTiming) {
768+
currentTrack = 'Gesture';
769+
// Clamp start times
770+
if (updateTime > 0) {
771+
if (updateTime > renderStartTime) {
772+
updateTime = renderStartTime;
773+
}
774+
} else {
775+
updateTime = renderStartTime;
776+
}
777+
if (startTime > 0) {
778+
if (startTime > updateTime) {
779+
startTime = updateTime;
780+
}
781+
} else {
782+
startTime = updateTime;
783+
}
784+
if (eventTime > 0) {
785+
if (eventTime > startTime) {
786+
eventTime = startTime;
787+
}
788+
} else {
789+
eventTime = startTime;
790+
}
791+
792+
if (startTime > eventTime && eventType !== null) {
793+
// Log the time from the event timeStamp until we started a gesture.
794+
const color = eventIsRepeat ? 'secondary-light' : 'warning';
795+
if (__DEV__ && debugTask) {
796+
debugTask.run(
797+
console.timeStamp.bind(
798+
console,
799+
eventIsRepeat ? 'Consecutive' : 'Event: ' + eventType,
800+
eventTime,
801+
startTime,
802+
currentTrack,
803+
LANES_TRACK_GROUP,
804+
color,
805+
),
806+
);
807+
} else {
808+
console.timeStamp(
809+
eventIsRepeat ? 'Consecutive' : 'Event: ' + eventType,
810+
eventTime,
811+
startTime,
812+
currentTrack,
813+
LANES_TRACK_GROUP,
814+
color,
815+
);
816+
}
817+
}
818+
if (updateTime > startTime) {
819+
// Log the time from when we started a gesture until we called setState or started rendering.
820+
if (__DEV__ && debugTask) {
821+
debugTask.run(
822+
// $FlowFixMe[method-unbinding]
823+
console.timeStamp.bind(
824+
console,
825+
'Gesture',
826+
startTime,
827+
updateTime,
828+
currentTrack,
829+
LANES_TRACK_GROUP,
830+
'primary-dark',
831+
),
832+
);
833+
} else {
834+
console.timeStamp(
835+
'Gesture',
836+
startTime,
837+
updateTime,
838+
currentTrack,
839+
LANES_TRACK_GROUP,
840+
'primary-dark',
841+
);
842+
}
843+
}
844+
if (renderStartTime > updateTime) {
845+
// Log the time from when we called setState until we started rendering.
846+
const label = isPingedUpdate
847+
? 'Promise Resolved'
848+
: renderStartTime - updateTime > 5
849+
? 'Update Blocked'
850+
: 'Update';
851+
if (__DEV__) {
852+
const properties = [];
853+
if (updateComponentName != null) {
854+
properties.push(['Component name', updateComponentName]);
855+
}
856+
if (updateMethodName != null) {
857+
properties.push(['Method name', updateMethodName]);
858+
}
859+
const measureOptions = {
860+
start: updateTime,
861+
end: renderStartTime,
862+
detail: {
863+
devtools: {
864+
properties,
865+
track: currentTrack,
866+
trackGroup: LANES_TRACK_GROUP,
867+
color: 'primary-light',
868+
},
869+
},
870+
};
871+
872+
if (debugTask) {
873+
debugTask.run(
874+
// $FlowFixMe[method-unbinding]
875+
performance.measure.bind(performance, label, measureOptions),
876+
);
877+
} else {
878+
performance.measure(label, measureOptions);
879+
}
880+
} else {
881+
console.timeStamp(
882+
label,
883+
updateTime,
884+
renderStartTime,
885+
currentTrack,
886+
LANES_TRACK_GROUP,
887+
'primary-light',
888+
);
889+
}
890+
}
891+
}
892+
}
893+
742894
export function logTransitionStart(
743895
startTime: number,
744896
updateTime: number,

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import {
7171
} from './Scheduler';
7272
import {
7373
logBlockingStart,
74+
logGestureStart,
7475
logTransitionStart,
7576
logRenderPhase,
7677
logInterruptedRenderPhase,
@@ -282,6 +283,17 @@ import {
282283
blockingEventType,
283284
blockingEventIsRepeat,
284285
blockingSuspendedTime,
286+
gestureClampTime,
287+
gestureStartTime,
288+
gestureUpdateTime,
289+
gestureUpdateTask,
290+
gestureUpdateType,
291+
gestureUpdateMethodName,
292+
gestureUpdateComponentName,
293+
gestureEventTime,
294+
gestureEventType,
295+
gestureEventIsRepeat,
296+
gestureSuspendedTime,
285297
transitionClampTime,
286298
transitionStartTime,
287299
transitionUpdateTime,
@@ -294,8 +306,10 @@ import {
294306
transitionEventIsRepeat,
295307
transitionSuspendedTime,
296308
clearBlockingTimers,
309+
clearGestureTimers,
297310
clearTransitionTimers,
298311
clampBlockingTimers,
312+
clampGestureTimers,
299313
clampTransitionTimers,
300314
clampRetryTimers,
301315
clampIdleTimers,
@@ -1898,7 +1912,9 @@ function resetWorkInProgressStack() {
18981912

18991913
function finalizeRender(lanes: Lanes, finalizationTime: number): void {
19001914
if (enableProfilerTimer && enableComponentPerformanceTrack) {
1901-
if (includesBlockingLane(lanes)) {
1915+
if (isGestureRender(lanes)) {
1916+
clampGestureTimers(finalizationTime);
1917+
} else if (includesBlockingLane(lanes)) {
19021918
clampBlockingTimers(finalizationTime);
19031919
}
19041920
if (includesTransitionLane(lanes)) {
@@ -1963,7 +1979,58 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
19631979
const previousUpdateTask = workInProgressUpdateTask;
19641980

19651981
workInProgressUpdateTask = null;
1966-
if (includesBlockingLane(lanes)) {
1982+
if (isGestureRender(lanes)) {
1983+
workInProgressUpdateTask = gestureUpdateTask;
1984+
const clampedStartTime =
1985+
gestureStartTime >= 0 && gestureStartTime < gestureClampTime
1986+
? gestureClampTime
1987+
: gestureStartTime;
1988+
const clampedUpdateTime =
1989+
gestureUpdateTime >= 0 && gestureUpdateTime < gestureClampTime
1990+
? gestureClampTime
1991+
: gestureUpdateTime;
1992+
const clampedEventTime =
1993+
gestureEventTime >= 0 && gestureEventTime < gestureClampTime
1994+
? gestureClampTime
1995+
: gestureEventTime;
1996+
const clampedRenderStartTime =
1997+
// Clamp the suspended time to the first event/update.
1998+
clampedEventTime >= 0
1999+
? clampedEventTime
2000+
: clampedUpdateTime >= 0
2001+
? clampedUpdateTime
2002+
: renderStartTime;
2003+
if (gestureSuspendedTime >= 0) {
2004+
setCurrentTrackFromLanes(GestureLane);
2005+
logSuspendedWithDelayPhase(
2006+
gestureSuspendedTime,
2007+
clampedRenderStartTime,
2008+
lanes,
2009+
workInProgressUpdateTask,
2010+
);
2011+
} else if (isGestureRender(animatingLanes)) {
2012+
// If this lane is still animating, log the time from previous render finishing to now as animating.
2013+
setCurrentTrackFromLanes(GestureLane);
2014+
logAnimatingPhase(
2015+
gestureClampTime,
2016+
clampedRenderStartTime,
2017+
animatingTask,
2018+
);
2019+
}
2020+
logGestureStart(
2021+
clampedStartTime,
2022+
clampedUpdateTime,
2023+
clampedEventTime,
2024+
gestureEventType,
2025+
gestureEventIsRepeat,
2026+
gestureUpdateType === PINGED_UPDATE,
2027+
renderStartTime,
2028+
gestureUpdateTask,
2029+
gestureUpdateMethodName,
2030+
gestureUpdateComponentName,
2031+
);
2032+
clearGestureTimers();
2033+
} else if (includesBlockingLane(lanes)) {
19672034
workInProgressUpdateTask = blockingUpdateTask;
19682035
const clampedUpdateTime =
19692036
blockingUpdateTime >= 0 && blockingUpdateTime < blockingClampTime
@@ -3716,12 +3783,12 @@ function finishedViewTransition(lanes: Lanes): void {
37163783
// If an affected track isn't in the middle of rendering or committing, log from the previous
37173784
// finished render until the end of the animation.
37183785
if (
3719-
includesBlockingLane(lanes) &&
3720-
!includesBlockingLane(workInProgressRootRenderLanes) &&
3721-
!includesBlockingLane(pendingEffectsLanes)
3786+
isGestureRender(lanes) &&
3787+
!isGestureRender(workInProgressRootRenderLanes) &&
3788+
!isGestureRender(pendingEffectsLanes)
37223789
) {
3723-
setCurrentTrackFromLanes(SyncLane);
3724-
logAnimatingPhase(blockingClampTime, now(), task);
3790+
setCurrentTrackFromLanes(GestureLane);
3791+
logAnimatingPhase(gestureClampTime, now(), task);
37253792
}
37263793
if (
37273794
includesTransitionLane(lanes) &&

0 commit comments

Comments
 (0)