Skip to content

Commit

Permalink
Defer work scheduler work if we're inside a pending commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sebmarkbage committed Jan 6, 2025
1 parent c24399a commit c55edd2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
14 changes: 14 additions & 0 deletions packages/react-reconciler/src/ReactFiberRootScheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
getWorkInProgressRootRenderLanes,
getRootWithPendingPassiveEffects,
getPendingPassiveEffectsLanes,
hasPendingCommitEffects,
isWorkLoopSuspendedOnData,
performWorkOnRoot,
} from './ReactFiberWorkLoop';
Expand Down Expand Up @@ -466,6 +467,19 @@ function performWorkOnRootViaSchedulerTask(
trackSchedulerEvent();
}

if (hasPendingCommitEffects()) {
// We are currently in the middle of an async committing (such as a View Transition).
// We could force these to flush eagerly but it's better to defer any work until
// it finishes. This may not be the same root as we're waiting on.
// TODO: This relies on the commit eventually calling ensureRootIsScheduled which
// always calls processRootScheduleInMicrotask which in turn always loops through
// all the roots to figure out. This is all a bit inefficient and if optimized
// it'll need to consider rescheduling a task for any skipped roots.
root.callbackNode = null;
root.callbackPriority = NoLane;
return null;
}

// Flush any pending passive effects before deciding which lanes to work on,
// in case they schedule additional work.
const originalCallbackNode = root.callbackNode;
Expand Down
5 changes: 5 additions & 0 deletions packages/react-reconciler/src/ReactFiberWorkLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,11 @@ export function getWorkInProgressRootRenderLanes(): Lanes {
return workInProgressRootRenderLanes;
}

export function hasPendingCommitEffects(): boolean {
return pendingEffectsStatus !== NO_PENDING_EFFECTS &&
pendingEffectsStatus !== PENDING_PASSIVE_PHASE;
}

export function getRootWithPendingPassiveEffects(): FiberRoot | null {
return pendingEffectsStatus === PENDING_PASSIVE_PHASE
? pendingEffectsRoot
Expand Down

0 comments on commit c55edd2

Please sign in to comment.