Skip to content

Commit c55edd2

Browse files
committed
Defer work scheduler work if we're inside a pending commit
1 parent c24399a commit c55edd2

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

packages/react-reconciler/src/ReactFiberRootScheduler.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
getWorkInProgressRootRenderLanes,
4545
getRootWithPendingPassiveEffects,
4646
getPendingPassiveEffectsLanes,
47+
hasPendingCommitEffects,
4748
isWorkLoopSuspendedOnData,
4849
performWorkOnRoot,
4950
} from './ReactFiberWorkLoop';
@@ -466,6 +467,19 @@ function performWorkOnRootViaSchedulerTask(
466467
trackSchedulerEvent();
467468
}
468469

470+
if (hasPendingCommitEffects()) {
471+
// We are currently in the middle of an async committing (such as a View Transition).
472+
// We could force these to flush eagerly but it's better to defer any work until
473+
// it finishes. This may not be the same root as we're waiting on.
474+
// TODO: This relies on the commit eventually calling ensureRootIsScheduled which
475+
// always calls processRootScheduleInMicrotask which in turn always loops through
476+
// all the roots to figure out. This is all a bit inefficient and if optimized
477+
// it'll need to consider rescheduling a task for any skipped roots.
478+
root.callbackNode = null;
479+
root.callbackPriority = NoLane;
480+
return null;
481+
}
482+
469483
// Flush any pending passive effects before deciding which lanes to work on,
470484
// in case they schedule additional work.
471485
const originalCallbackNode = root.callbackNode;

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,11 @@ export function getWorkInProgressRootRenderLanes(): Lanes {
657657
return workInProgressRootRenderLanes;
658658
}
659659

660+
export function hasPendingCommitEffects(): boolean {
661+
return pendingEffectsStatus !== NO_PENDING_EFFECTS &&
662+
pendingEffectsStatus !== PENDING_PASSIVE_PHASE;
663+
}
664+
660665
export function getRootWithPendingPassiveEffects(): FiberRoot | null {
661666
return pendingEffectsStatus === PENDING_PASSIVE_PHASE
662667
? pendingEffectsRoot

0 commit comments

Comments
 (0)