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.
This commit is contained in:
Andrew Clark
2020-01-29 11:32:20 -08:00
parent 36bf07f430
commit 7c100bfed4
+10 -3
View File
@@ -644,9 +644,16 @@ function performConcurrentWorkOnRoot(root, didTimeout) {
// event time. The next update will compute a new event time.
currentEventTime = NoWork;
if (didTimeout) {
// The render task took too long to complete. Mark the current time as
// expired to synchronously render all expired work in a single batch.
// Check if the render expired. If so, restart at the current time so that we
// can finish all the expired work in a single batch. However, we should only
// do this if we're starting a new tree. If we're in the middle of an existing
// tree, we'll continue working on that (without yielding) so that the work
// doesn't get dropped. If there's another expired level after that, we'll hit
// this path again, at which point we can batch all the subsequent levels
// together.
if (didTimeout && workInProgress === null) {
// Mark the current time as expired to synchronously render all expired work
// in a single batch.
const currentTime = requestCurrentTimeForUpdate();
markRootExpiredAtTime(root, currentTime);
// This will schedule a synchronous callback.