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
4 changes: 4 additions & 0 deletions packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -2100,6 +2100,7 @@ export function startViewTransition(
passiveCallback: () => mixed,
errorCallback: mixed => void,
blockedCallback: string => void, // Profiling-only
finishedAnimation: () => void, // Profiling-only
): null | RunningViewTransition {
const ownerDocument: Document =
rootContainer.nodeType === DOCUMENT_NODE
Expand Down Expand Up @@ -2302,6 +2303,9 @@ export function startViewTransition(
// $FlowFixMe[prop-missing]
ownerDocument.__reactViewTransition = null;
}
if (enableProfilerTimer) {
finishedAnimation();
}
passiveCallback();
});
return transition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ export function startViewTransition(
passiveCallback: () => mixed,
errorCallback: mixed => void,
blockedCallback: string => void, // Profiling-only
finishedAnimation: () => void, // Profiling-only
): null | RunningViewTransition {
mutationCallback();
layoutCallback();
Expand Down
2 changes: 2 additions & 0 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,8 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
spawnedWorkCallback: () => void,
passiveCallback: () => mixed,
errorCallback: mixed => void,
blockedCallback: string => void, // Profiling-only
finishedAnimation: () => void, // Profiling-only
): null | RunningViewTransition {
mutationCallback();
layoutCallback();
Expand Down
18 changes: 18 additions & 0 deletions packages/react-reconciler/src/ReactFiberLane.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ const TransitionLane12: Lane = /* */ 0b0000000000010000000
const TransitionLane13: Lane = /* */ 0b0000000000100000000000000000000;
const TransitionLane14: Lane = /* */ 0b0000000001000000000000000000000;

export const SomeTransitionLane: Lane = TransitionLane1;

const TransitionUpdateLanes =
TransitionLane1 |
TransitionLane2 |
Expand Down Expand Up @@ -633,6 +635,22 @@ export function includesTransitionLane(lanes: Lanes): boolean {
return (lanes & TransitionLanes) !== NoLanes;
}

export function includesRetryLane(lanes: Lanes): boolean {
return (lanes & RetryLanes) !== NoLanes;
}

export function includesIdleGroupLanes(lanes: Lanes): boolean {
return (
(lanes &
(SelectiveHydrationLane |
IdleHydrationLane |
IdleLane |
OffscreenLane |
DeferredLane)) !==
NoLanes
);
}

export function includesOnlyHydrationLanes(lanes: Lanes): boolean {
return (lanes & HydrationLanes) === lanes;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react-reconciler/src/ReactFiberPerformanceTrack.js
Original file line number Diff line number Diff line change
Expand Up @@ -1458,7 +1458,7 @@ export function logAnimatingPhase(
endTime,
currentTrack,
LANES_TRACK_GROUP,
'secondary',
'secondary-dark',
),
);
} else {
Expand All @@ -1468,7 +1468,7 @@ export function logAnimatingPhase(
endTime,
currentTrack,
LANES_TRACK_GROUP,
'secondary',
'secondary-dark',
);
}
}
Expand Down
154 changes: 137 additions & 17 deletions packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ import {
includesOnlyTransitions,
includesBlockingLane,
includesTransitionLane,
includesRetryLane,
includesIdleGroupLanes,
includesExpiredLane,
getNextLanes,
getEntangledLanes,
Expand All @@ -201,6 +203,9 @@ import {
includesOnlyViewTransitionEligibleLanes,
isGestureRender,
GestureLane,
SomeTransitionLane,
SomeRetryLane,
IdleLane,
} from './ReactFiberLane';
import {
DiscreteEventPriority,
Expand Down Expand Up @@ -292,6 +297,8 @@ import {
clearTransitionTimers,
clampBlockingTimers,
clampTransitionTimers,
clampRetryTimers,
clampIdleTimers,
markNestedUpdateScheduled,
renderStartTime,
commitStartTime,
Expand All @@ -312,6 +319,11 @@ import {
resetCommitErrors,
PINGED_UPDATE,
SPAWNED_UPDATE,
startAnimating,
stopAnimating,
animatingLanes,
retryClampTime,
idleClampTime,
} from './ReactProfilerTimer';

// DEV stuff
Expand Down Expand Up @@ -1426,6 +1438,7 @@ function finishConcurrentRender(
// immediately, wait for more data to arrive.
// TODO: Combine retry throttling with Suspensey commits. Right now they
// run one after the other.
pendingEffectsLanes = lanes;
root.timeoutHandle = scheduleTimeout(
commitRootWhenReady.bind(
null,
Expand Down Expand Up @@ -1539,6 +1552,7 @@ function commitRootWhenReady(
// Not yet ready to commit. Delay the commit until the renderer notifies
// us that it's ready. This will be canceled if we start work on the
// root again.
pendingEffectsLanes = lanes;
root.cancelPendingCommit = schedulePendingCommit(
commitRoot.bind(
null,
Expand Down Expand Up @@ -1889,6 +1903,12 @@ function finalizeRender(lanes: Lanes, finalizationTime: number): void {
if (includesTransitionLane(lanes)) {
clampTransitionTimers(finalizationTime);
}
if (includesRetryLane(lanes)) {
clampRetryTimers(finalizationTime);
}
if (includesIdleGroupLanes(lanes)) {
clampIdleTimers(finalizationTime);
}
}
}

Expand Down Expand Up @@ -1939,6 +1959,7 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
}
finalizeRender(workInProgressRootRenderLanes, renderStartTime);
}
const previousUpdateTask = workInProgressUpdateTask;

workInProgressUpdateTask = null;
if (includesSyncLane(lanes) || includesBlockingLane(lanes)) {
Expand All @@ -1951,18 +1972,30 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
blockingEventTime >= 0 && blockingEventTime < blockingClampTime
? blockingClampTime
: blockingEventTime;
const clampedRenderStartTime = // Clamp the suspended time to the first event/update.
clampedEventTime >= 0
? clampedEventTime
: clampedUpdateTime >= 0
? clampedUpdateTime
: renderStartTime;
if (blockingSuspendedTime >= 0) {
setCurrentTrackFromLanes(lanes);
setCurrentTrackFromLanes(SyncLane);
logSuspendedWithDelayPhase(
blockingSuspendedTime,
// Clamp the suspended time to the first event/update.
clampedEventTime >= 0
? clampedEventTime
: clampedUpdateTime >= 0
? clampedUpdateTime
: renderStartTime,
clampedRenderStartTime,
lanes,
workInProgressUpdateTask,
previousUpdateTask,
);
} else if (
includesSyncLane(animatingLanes) ||
includesBlockingLane(animatingLanes)
) {
// If this lane is still animating, log the time from previous render finishing to now as animating.
setCurrentTrackFromLanes(SyncLane);
logAnimatingPhase(
blockingClampTime,
clampedRenderStartTime,
previousUpdateTask,
);
}
logBlockingStart(
Expand Down Expand Up @@ -1994,19 +2027,29 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
transitionEventTime >= 0 && transitionEventTime < transitionClampTime
? transitionClampTime
: transitionEventTime;
const clampedRenderStartTime =
// Clamp the suspended time to the first event/update.
clampedEventTime >= 0
? clampedEventTime
: clampedUpdateTime >= 0
? clampedUpdateTime
: renderStartTime;
if (transitionSuspendedTime >= 0) {
setCurrentTrackFromLanes(lanes);
setCurrentTrackFromLanes(SomeTransitionLane);
logSuspendedWithDelayPhase(
transitionSuspendedTime,
// Clamp the suspended time to the first event/update.
clampedEventTime >= 0
? clampedEventTime
: clampedUpdateTime >= 0
? clampedUpdateTime
: renderStartTime,
clampedRenderStartTime,
lanes,
workInProgressUpdateTask,
);
} else if (includesTransitionLane(animatingLanes)) {
// If this lane is still animating, log the time from previous render finishing to now as animating.
setCurrentTrackFromLanes(SomeTransitionLane);
logAnimatingPhase(
transitionClampTime,
clampedRenderStartTime,
previousUpdateTask,
);
}
logTransitionStart(
clampedStartTime,
Expand All @@ -2022,6 +2065,20 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
);
clearTransitionTimers();
}
if (includesRetryLane(lanes)) {
if (includesRetryLane(animatingLanes)) {
// If this lane is still animating, log the time from previous render finishing to now as animating.
setCurrentTrackFromLanes(SomeRetryLane);
logAnimatingPhase(retryClampTime, renderStartTime, previousUpdateTask);
}
}
if (includesIdleGroupLanes(lanes)) {
if (includesIdleGroupLanes(animatingLanes)) {
// If this lane is still animating, log the time from previous render finishing to now as animating.
setCurrentTrackFromLanes(IdleLane);
logAnimatingPhase(idleClampTime, renderStartTime, previousUpdateTask);
}
}
}

const timeoutHandle = root.timeoutHandle;
Expand All @@ -2038,6 +2095,8 @@ function prepareFreshStack(root: FiberRoot, lanes: Lanes): Fiber {
cancelPendingCommit();
}

pendingEffectsLanes = NoLanes;

resetWorkInProgressStack();
workInProgressRoot = root;
const rootWorkInProgress = createWorkInProgress(root.current, null);
Expand Down Expand Up @@ -3592,6 +3651,9 @@ function commitRoot(

pendingEffectsStatus = PENDING_MUTATION_PHASE;
if (enableViewTransition && willStartViewTransition) {
if (enableProfilerTimer && enableComponentPerformanceTrack) {
startAnimating(lanes);
}
pendingViewTransition = startViewTransition(
suspendedState,
root.containerInfo,
Expand All @@ -3603,6 +3665,15 @@ function commitRoot(
flushPassiveEffects,
reportViewTransitionError,
enableProfilerTimer ? suspendedViewTransition : (null: any),
enableProfilerTimer
? // This callback fires after "pendingEffects" so we need to snapshot the arguments.
finishedViewTransition.bind(
null,
lanes,
// TODO: Use a ViewTransition Task
__DEV__ ? workInProgressUpdateTask : null,
)
: (null: any),
);
} else {
// Flush synchronously.
Expand Down Expand Up @@ -3634,13 +3705,62 @@ function suspendedViewTransition(reason: string): void {
commitEndTime,
commitErrors,
pendingDelayedCommitReason === ABORTED_VIEW_TRANSITION_COMMIT,
workInProgressUpdateTask,
workInProgressUpdateTask, // TODO: Use a ViewTransition Task and this is not safe to read in this phase.
);
pendingSuspendedViewTransitionReason = reason;
pendingSuspendedCommitReason = reason;
}
}

function finishedViewTransition(
lanes: Lanes,
task: null | ConsoleTask, // DEV-only
): void {
if (enableProfilerTimer && enableComponentPerformanceTrack) {
if ((animatingLanes & lanes) === NoLanes) {
// Was already stopped by some other action or maybe other root.
return;
}
stopAnimating(lanes);
// 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 (
(includesSyncLane(lanes) || includesBlockingLane(lanes)) &&
!includesSyncLane(workInProgressRootRenderLanes) &&
!includesBlockingLane(workInProgressRootRenderLanes) &&
!includesSyncLane(pendingEffectsLanes) &&
!includesBlockingLane(pendingEffectsLanes)
) {
setCurrentTrackFromLanes(SyncLane);
logAnimatingPhase(blockingClampTime, now(), task);
}
if (
includesTransitionLane(lanes) &&
!includesTransitionLane(workInProgressRootRenderLanes) &&
!includesTransitionLane(pendingEffectsLanes)
) {
setCurrentTrackFromLanes(SomeTransitionLane);
logAnimatingPhase(transitionClampTime, now(), task);
}
if (
includesRetryLane(lanes) &&
!includesRetryLane(workInProgressRootRenderLanes) &&
!includesRetryLane(pendingEffectsLanes)
) {
setCurrentTrackFromLanes(SomeRetryLane);
logAnimatingPhase(retryClampTime, now(), task);
}
if (
includesIdleGroupLanes(lanes) &&
!includesIdleGroupLanes(workInProgressRootRenderLanes) &&
!includesIdleGroupLanes(pendingEffectsLanes)
) {
setCurrentTrackFromLanes(IdleLane);
logAnimatingPhase(idleClampTime, now(), task);
}
}
}

function flushAfterMutationEffects(): void {
if (pendingEffectsStatus !== PENDING_AFTER_MUTATION_PHASE) {
return;
Expand Down Expand Up @@ -3715,7 +3835,7 @@ function flushLayoutEffects(): void {
commitEndTime, // The start is the end of the first commit part.
commitStartTime, // The end is the start of the second commit part.
suspendedViewTransitionReason,
workInProgressUpdateTask,
workInProgressUpdateTask, // TODO: Use a ViewTransition Task and this is not safe to read in this phase.
);
}
}
Expand Down
Loading
Loading