-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make prerendering always non-blocking with fix #31452
Make prerendering always non-blocking with fix #31452
Conversation
When a synchronous update suspends, and we prerender the siblings, the prerendering should be non-blocking so that we can immediately restart once the data arrives. This happens automatically when there's a Suspense boundary, because we immediately commit the boundary and then proceed to a Retry render, which are always concurrent. When there's not a Suspense boundary, there is no Retry, so we need to take care to switch from the synchronous work loop to the concurrent one, to enable time slicing.
We are getting infinite sync render loops from useSyncExternalStore render phase updates (Recoil). renderWasConcurrent within the do block made the sync pass pin the exitStatus to RootSuspended.
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
let renderWasConcurrent = shouldTimeSlice; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
facepalm, could happen to anyone but damn this was hard to find
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DUDE. Amazing job debugging this, @jackpope and @rickhanlonii! Since the main code was already reviewed originally let's go ahead and land.
Just a couple comments on the test case, looks like some bits are maybe unused/unnecessary for the repro.
} | ||
} | ||
|
||
function useBug<TValue>(path: string): SRConfigPathState<TValue> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the type here?
We've previously failed to land this change due to some internal apps seeing infinite render loops due to external store state updates during render. It turns out that since the `renderWasConcurrent` var was moved into the do block, the sync render triggered from the external store check was stuck with a `RootSuspended` `exitStatus`. So this is not unique to sibling prerendering but more generally related to how we handle update to a sync external store during render. We've tested this build against local repros which now render without crashes. We will try to add a unit test to cover the scenario as well. --------- Co-authored-by: Andrew Clark <[email protected]> Co-authored-by: Rick Hanlon <[email protected]> DiffTrain build for [989af12](989af12)
We've previously failed to land this change due to some internal apps seeing infinite render loops due to external store state updates during render. It turns out that since the `renderWasConcurrent` var was moved into the do block, the sync render triggered from the external store check was stuck with a `RootSuspended` `exitStatus`. So this is not unique to sibling prerendering but more generally related to how we handle update to a sync external store during render. We've tested this build against local repros which now render without crashes. We will try to add a unit test to cover the scenario as well. --------- Co-authored-by: Andrew Clark <[email protected]> Co-authored-by: Rick Hanlon <[email protected]> DiffTrain build for [989af12](989af12)
We've previously failed to land this change due to some internal apps seeing infinite render loops due to external store state updates during render. It turns out that since the
renderWasConcurrent
var was moved into the do block, the sync render triggered from the external store check was stuck with aRootSuspended
exitStatus
. So this is not unique to sibling prerendering but more generally related to how we handle update to a sync external store during render.We've tested this build against local repros which now render without crashes. We will try to add a unit test to cover the scenario as well.