Skip to content

Commit fc79757

Browse files
committed
Check if there's a partial tree before restarting
If a partial render expires, we should stay in the concurrent path (performConcurrentWorkOnRoot); we'll stop yielding, but the rest of the behavior remains the same. We will only revert to the sync path (performSyncWorkOnRoot) when starting on a new level. This approach prevents partially completed concurrent work from being discarded.
1 parent 36bf07f commit fc79757

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,16 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
644644
// event time. The next update will compute a new event time.
645645
currentEventTime = NoWork;
646646

647-
if (didTimeout) {
648-
// The render task took too long to complete. Mark the current time as
649-
// expired to synchronously render all expired work in a single batch.
647+
// Check if the render expired. If so, restart at the current time so that we
648+
// can finish all the expired work in a single batch. However, we should only
649+
// do this if we're starting a new tree. If we're in the middle of an existing
650+
// tree, we'll continue working on that (without yielding) so that the work
651+
// doesn't get dropped. If there's another expired level after that, we'll hit
652+
// this path again, at which point we can batch all the subsequent levels
653+
// together.
654+
if (didTimeout && workInProgress === null) {
655+
// Mark the current time as expired to synchronously render all expired work
656+
// in a single batch.
650657
const currentTime = requestCurrentTimeForUpdate();
651658
markRootExpiredAtTime(root, currentTime);
652659
// This will schedule a synchronous callback.

0 commit comments

Comments
 (0)