-
Notifications
You must be signed in to change notification settings - Fork 47.7k
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
[Flight] Resolve deduped references when chunks are blocked on each other #32316
base: main
Are you sure you want to change the base?
[Flight] Resolve deduped references when chunks are blocked on each other #32316
Conversation
414c443
to
ecb5a8a
Compare
packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js
Show resolved
Hide resolved
@@ -163,6 +163,7 @@ type BlockedChunk<T> = { | |||
status: 'blocked', | |||
value: null | Array<(T) => mixed>, | |||
reason: null | Array<(mixed) => mixed>, | |||
intermediaryValue?: mixed, | |||
_response: Response, | |||
_children: Array<SomeChunk<any>> | ProfilingResult, // Profiling-only |
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.
This is not "Profiling-only" anymore. I'm not sure this is actually reliable enough. It's more of a hack for profiling which is optional if it works or not.
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.
I think we can keep _children
profiling-only. It was not necessary for this fix to remove the two guards around initializingChunk._children
. I reverted that.
@@ -3393,6 +3410,7 @@ function parseModel<T>(response: Response, json: UninitializedModel): T { | |||
function createFromJSONCallback(response: Response) { | |||
// $FlowFixMe[missing-this-annot] | |||
return function (key: string, value: JSONValue) { | |||
isParsingRootModel = key === ''; |
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.
We can't assume that an empty string key is the root since it may also be on nested objects. What's the implication of that?
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.
Hmm, we were already using the check here:
react/packages/react-client/src/ReactFlightClient.js
Lines 983 to 987 in 192555b
// If this is the root object for a model reference, where `handler.value` | |
// is a stale `null`, the resolved value can be used directly. | |
if (key === '' && handler.value === null) { | |
handler.value = mappedValue; | |
} |
But I guess you're right, it could also be an explicit empty key in some object.
This PR includes a reduced test case of vercel/next.js#75726:
This is serialized into the following RSC payload which the Flight Client was not able to resolve, because two chunks are blocked on each other:
We can fix this by storing intermediary values (only elements for now) on the initializing chunk. When the
fulfill
listener inwaitForReference
is called with a lazy element that has a blocked chunk, which is not the current chunk, we can peek into the intermediary value of the referenced chunk to resolve a reference for a different chunk that's still blocked.fixes vercel/next.js#72104