Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions packages/react-reconciler/src/ReactFiberLane.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
retryLaneExpirationMs,
disableLegacyMode,
enableDefaultTransitionIndicator,
enableGestureTransition,
} from 'shared/ReactFeatureFlags';
import {isDevToolsPresent} from './ReactFiberDevToolsHook';
import {clz32} from './clz32';
Expand Down Expand Up @@ -710,6 +711,9 @@ export function isTransitionLane(lane: Lane): boolean {
}

export function isGestureRender(lanes: Lanes): boolean {
if (!enableGestureTransition) {
return false;
}
// This should render only the one lane.
return lanes === GestureLane;
}
Expand Down Expand Up @@ -1271,11 +1275,13 @@ export function getGroupNameOfHighestPriorityLane(lanes: Lanes): string {
InputContinuousHydrationLane |
InputContinuousLane |
DefaultHydrationLane |
DefaultLane |
GestureLane)
DefaultLane)
) {
return 'Blocking';
}
if (lanes & GestureLane) {
return 'Gesture';
}
if (lanes & (TransitionHydrationLane | TransitionLanes)) {
return 'Transition';
}
Expand Down
154 changes: 153 additions & 1 deletion packages/react-reconciler/src/ReactFiberPerformanceTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ import {
addObjectDiffToProperties,
} from 'shared/ReactPerformanceTrackProperties';

import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
import {
enableProfilerTimer,
enableGestureTransition,
} from 'shared/ReactFeatureFlags';

const supportsUserTiming =
enableProfilerTimer &&
Expand Down Expand Up @@ -68,6 +71,16 @@ export function markAllLanesInOrder() {
LANES_TRACK_GROUP,
'primary-light',
);
if (enableGestureTransition) {
console.timeStamp(
'Gesture Track',
0.003,
0.003,
'Gesture',
LANES_TRACK_GROUP,
'primary-light',
);
}
console.timeStamp(
'Transition Track',
0.003,
Expand Down Expand Up @@ -739,6 +752,145 @@ export function logBlockingStart(
}
}

export function logGestureStart(
startTime: number,
updateTime: number,
eventTime: number,
eventType: null | string,
eventIsRepeat: boolean,
isPingedUpdate: boolean,
renderStartTime: number,
debugTask: null | ConsoleTask, // DEV-only
updateMethodName: null | string,
updateComponentName: null | string,
): void {
if (supportsUserTiming) {
currentTrack = 'Gesture';
// Clamp start times
if (updateTime > 0) {
if (updateTime > renderStartTime) {
updateTime = renderStartTime;
}
} else {
updateTime = renderStartTime;
}
if (startTime > 0) {
if (startTime > updateTime) {
startTime = updateTime;
}
} else {
startTime = updateTime;
}
if (eventTime > 0) {
if (eventTime > startTime) {
eventTime = startTime;
}
} else {
eventTime = startTime;
}

if (startTime > eventTime && eventType !== null) {
// Log the time from the event timeStamp until we started a gesture.
const color = eventIsRepeat ? 'secondary-light' : 'warning';
if (__DEV__ && debugTask) {
debugTask.run(
console.timeStamp.bind(
console,
eventIsRepeat ? 'Consecutive' : 'Event: ' + eventType,
eventTime,
startTime,
currentTrack,
LANES_TRACK_GROUP,
color,
),
);
} else {
console.timeStamp(
eventIsRepeat ? 'Consecutive' : 'Event: ' + eventType,
eventTime,
startTime,
currentTrack,
LANES_TRACK_GROUP,
color,
);
}
}
if (updateTime > startTime) {
// Log the time from when we started a gesture until we called setState or started rendering.
if (__DEV__ && debugTask) {
debugTask.run(
// $FlowFixMe[method-unbinding]
console.timeStamp.bind(
console,
'Gesture',
startTime,
updateTime,
currentTrack,
LANES_TRACK_GROUP,
'primary-dark',
),
);
} else {
console.timeStamp(
'Gesture',
startTime,
updateTime,
currentTrack,
LANES_TRACK_GROUP,
'primary-dark',
);
}
}
if (renderStartTime > updateTime) {
// Log the time from when we called setState until we started rendering.
const label = isPingedUpdate
? 'Promise Resolved'
: renderStartTime - updateTime > 5
? 'Update Blocked'
: 'Update';
if (__DEV__) {
const properties = [];
if (updateComponentName != null) {
properties.push(['Component name', updateComponentName]);
}
if (updateMethodName != null) {
properties.push(['Method name', updateMethodName]);
}
const measureOptions = {
start: updateTime,
end: renderStartTime,
detail: {
devtools: {
properties,
track: currentTrack,
trackGroup: LANES_TRACK_GROUP,
color: 'primary-light',
},
},
};

if (debugTask) {
debugTask.run(
// $FlowFixMe[method-unbinding]
performance.measure.bind(performance, label, measureOptions),
);
} else {
performance.measure(label, measureOptions);
}
} else {
console.timeStamp(
label,
updateTime,
renderStartTime,
currentTrack,
LANES_TRACK_GROUP,
'primary-light',
);
}
}
}
}

export function logTransitionStart(
startTime: number,
updateTime: number,
Expand Down
81 changes: 74 additions & 7 deletions packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import {
} from './Scheduler';
import {
logBlockingStart,
logGestureStart,
logTransitionStart,
logRenderPhase,
logInterruptedRenderPhase,
Expand Down Expand Up @@ -282,6 +283,17 @@ import {
blockingEventType,
blockingEventIsRepeat,
blockingSuspendedTime,
gestureClampTime,
gestureStartTime,
gestureUpdateTime,
gestureUpdateTask,
gestureUpdateType,
gestureUpdateMethodName,
gestureUpdateComponentName,
gestureEventTime,
gestureEventType,
gestureEventIsRepeat,
gestureSuspendedTime,
transitionClampTime,
transitionStartTime,
transitionUpdateTime,
Expand All @@ -294,8 +306,10 @@ import {
transitionEventIsRepeat,
transitionSuspendedTime,
clearBlockingTimers,
clearGestureTimers,
clearTransitionTimers,
clampBlockingTimers,
clampGestureTimers,
clampTransitionTimers,
clampRetryTimers,
clampIdleTimers,
Expand Down Expand Up @@ -1898,7 +1912,9 @@ function resetWorkInProgressStack() {

function finalizeRender(lanes: Lanes, finalizationTime: number): void {
if (enableProfilerTimer && enableComponentPerformanceTrack) {
if (includesBlockingLane(lanes)) {
if (isGestureRender(lanes)) {
clampGestureTimers(finalizationTime);
} else if (includesBlockingLane(lanes)) {
clampBlockingTimers(finalizationTime);
}
if (includesTransitionLane(lanes)) {
Expand Down Expand Up @@ -1963,7 +1979,58 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
const previousUpdateTask = workInProgressUpdateTask;

workInProgressUpdateTask = null;
if (includesBlockingLane(lanes)) {
if (isGestureRender(lanes)) {
workInProgressUpdateTask = gestureUpdateTask;
const clampedStartTime =
gestureStartTime >= 0 && gestureStartTime < gestureClampTime
? gestureClampTime
: gestureStartTime;
const clampedUpdateTime =
gestureUpdateTime >= 0 && gestureUpdateTime < gestureClampTime
? gestureClampTime
: gestureUpdateTime;
const clampedEventTime =
gestureEventTime >= 0 && gestureEventTime < gestureClampTime
? gestureClampTime
: gestureEventTime;
const clampedRenderStartTime =
// Clamp the suspended time to the first event/update.
clampedEventTime >= 0
? clampedEventTime
: clampedUpdateTime >= 0
? clampedUpdateTime
: renderStartTime;
if (gestureSuspendedTime >= 0) {
setCurrentTrackFromLanes(GestureLane);
logSuspendedWithDelayPhase(
gestureSuspendedTime,
clampedRenderStartTime,
lanes,
workInProgressUpdateTask,
);
} else if (isGestureRender(animatingLanes)) {
// If this lane is still animating, log the time from previous render finishing to now as animating.
setCurrentTrackFromLanes(GestureLane);
logAnimatingPhase(
gestureClampTime,
clampedRenderStartTime,
animatingTask,
);
}
logGestureStart(
clampedStartTime,
clampedUpdateTime,
clampedEventTime,
gestureEventType,
gestureEventIsRepeat,
gestureUpdateType === PINGED_UPDATE,
renderStartTime,
gestureUpdateTask,
gestureUpdateMethodName,
gestureUpdateComponentName,
);
clearGestureTimers();
} else if (includesBlockingLane(lanes)) {
workInProgressUpdateTask = blockingUpdateTask;
const clampedUpdateTime =
blockingUpdateTime >= 0 && blockingUpdateTime < blockingClampTime
Expand Down Expand Up @@ -3716,12 +3783,12 @@ function finishedViewTransition(lanes: Lanes): void {
// If an affected track isn't in the middle of rendering or committing, log from the previous
// finished render until the end of the animation.
if (
includesBlockingLane(lanes) &&
!includesBlockingLane(workInProgressRootRenderLanes) &&
!includesBlockingLane(pendingEffectsLanes)
isGestureRender(lanes) &&
!isGestureRender(workInProgressRootRenderLanes) &&
!isGestureRender(pendingEffectsLanes)
) {
setCurrentTrackFromLanes(SyncLane);
logAnimatingPhase(blockingClampTime, now(), task);
setCurrentTrackFromLanes(GestureLane);
logAnimatingPhase(gestureClampTime, now(), task);
}
if (
includesTransitionLane(lanes) &&
Expand Down
Loading
Loading