Skip to content
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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

unstubbable
Copy link
Collaborator

@unstubbable unstubbable commented Feb 6, 2025

This PR includes a reduced test case of vercel/next.js#75726:

function Server() {
  const shared = {id: 42};
  const map = new Map([[42, shared]]);

  return <ClientComponent shared={shared} map={map} />;
}

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:

1:I["0",[],"*"]
2:[[42,"$0:props:shared"]]
0:["$","$L1",null,{"shared":{"id":42},"map":"$Q2"}]

We can fix this by storing intermediary values (only elements for now) on the initializing chunk. When the fulfill listener in waitForReference 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

@react-sizebot
Copy link

react-sizebot commented Feb 6, 2025

Comparing: 93b5836...b573e1c

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.js = 6.68 kB 6.68 kB = 1.83 kB 1.83 kB
oss-stable/react-dom/cjs/react-dom-client.production.js = 515.48 kB 515.48 kB = 92.04 kB 92.04 kB
oss-experimental/react-dom/cjs/react-dom.production.js = 6.69 kB 6.69 kB = 1.83 kB 1.83 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js = 558.52 kB 558.52 kB = 99.27 kB 99.27 kB
facebook-www/ReactDOM-prod.classic.js = 636.88 kB 636.88 kB = 111.92 kB 111.92 kB
facebook-www/ReactDOM-prod.modern.js = 627.20 kB 627.20 kB = 110.34 kB 110.34 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.js +1.14% 82.03 kB 82.96 kB +1.36% 17.22 kB 17.46 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.js +1.14% 82.03 kB 82.96 kB +1.36% 17.22 kB 17.46 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.js +1.13% 82.76 kB 83.70 kB +1.36% 17.34 kB 17.57 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.production.js +1.13% 50.22 kB 50.78 kB +1.08% 10.17 kB 10.28 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.production.js +1.13% 50.22 kB 50.78 kB +1.08% 10.17 kB 10.28 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.js +1.13% 50.43 kB 51.00 kB +1.07% 10.29 kB 10.40 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.js +1.13% 50.43 kB 51.00 kB +1.07% 10.29 kB 10.40 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.production.js +1.12% 50.76 kB 51.33 kB +1.03% 10.26 kB 10.37 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.js +1.12% 50.98 kB 51.54 kB +0.99% 10.39 kB 10.49 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.js +1.09% 52.34 kB 52.91 kB +1.01% 10.68 kB 10.79 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.js +1.09% 52.34 kB 52.91 kB +1.01% 10.68 kB 10.79 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js +1.08% 52.77 kB 53.34 kB +1.03% 10.79 kB 10.90 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js +1.08% 52.77 kB 53.34 kB +1.03% 10.79 kB 10.90 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.js +1.08% 52.89 kB 53.46 kB +0.93% 10.78 kB 10.88 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.js +1.07% 53.32 kB 53.89 kB +0.94% 10.88 kB 10.99 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.production.js +1.06% 53.61 kB 54.18 kB +0.94% 11.03 kB 11.14 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.production.js +1.06% 53.61 kB 54.18 kB +0.94% 11.03 kB 11.14 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.production.js +1.05% 54.15 kB 54.72 kB +0.94% 11.12 kB 11.23 kB
oss-stable-semver/react-client/cjs/react-client-flight.production.js +1.05% 57.18 kB 57.78 kB +1.13% 10.65 kB 10.77 kB
oss-stable/react-client/cjs/react-client-flight.production.js +1.05% 57.20 kB 57.80 kB +1.11% 10.68 kB 10.79 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.js +1.05% 54.35 kB 54.92 kB +0.92% 11.15 kB 11.26 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.js +1.05% 54.35 kB 54.92 kB +0.92% 11.15 kB 11.26 kB
oss-experimental/react-client/cjs/react-client-flight.production.js +1.04% 57.66 kB 58.26 kB +1.04% 10.75 kB 10.87 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.js +1.04% 54.89 kB 55.46 kB +0.92% 11.24 kB 11.34 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.production.js +1.03% 55.14 kB 55.71 kB +0.93% 11.34 kB 11.45 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.production.js +1.03% 55.14 kB 55.71 kB +0.93% 11.34 kB 11.45 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.production.js +1.02% 55.69 kB 56.26 kB +0.90% 11.43 kB 11.54 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.js +1.00% 56.68 kB 57.25 kB +0.95% 11.61 kB 11.72 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.js +1.00% 56.68 kB 57.25 kB +0.95% 11.61 kB 11.72 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.js +0.99% 57.22 kB 57.79 kB +0.88% 11.70 kB 11.80 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.js +0.98% 58.17 kB 58.74 kB +0.89% 11.92 kB 12.03 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.js +0.98% 58.17 kB 58.74 kB +0.89% 11.92 kB 12.03 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.js +0.98% 58.26 kB 58.83 kB +0.89% 11.95 kB 12.05 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.js +0.98% 58.26 kB 58.83 kB +0.89% 11.95 kB 12.05 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.js +0.97% 58.72 kB 59.29 kB +0.87% 12.01 kB 12.11 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.js +0.97% 58.80 kB 59.37 kB +0.85% 12.03 kB 12.14 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.js +0.96% 59.19 kB 59.76 kB +0.89% 11.90 kB 12.01 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.js +0.96% 59.19 kB 59.76 kB +0.89% 11.90 kB 12.01 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.js +0.95% 59.72 kB 60.29 kB +0.88% 12.00 kB 12.10 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.js +0.94% 60.37 kB 60.94 kB +0.87% 12.14 kB 12.25 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.js +0.94% 60.37 kB 60.94 kB +0.87% 12.14 kB 12.25 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.js +0.93% 60.89 kB 61.46 kB +0.86% 12.23 kB 12.34 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.76% 123.44 kB 124.37 kB +0.87% 28.59 kB 28.84 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.76% 123.46 kB 124.40 kB +0.86% 28.61 kB 28.86 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.72% 88.25 kB 88.89 kB +0.71% 16.82 kB 16.94 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.72% 88.30 kB 88.94 kB +0.69% 16.84 kB 16.96 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.development.js +0.72% 88.61 kB 89.25 kB +0.72% 16.77 kB 16.89 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.development.js +0.72% 88.66 kB 89.30 kB +0.71% 16.79 kB 16.91 kB
oss-stable-semver/react-client/cjs/react-client-flight.development.js +0.71% 89.60 kB 90.24 kB +0.79% 16.41 kB 16.54 kB
oss-stable/react-client/cjs/react-client-flight.development.js +0.71% 89.63 kB 90.27 kB +0.79% 16.44 kB 16.57 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.71% 90.44 kB 91.07 kB +0.70% 17.20 kB 17.32 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.71% 90.49 kB 91.12 kB +0.70% 17.23 kB 17.35 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.70% 90.99 kB 91.63 kB +0.68% 17.33 kB 17.45 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.70% 91.04 kB 91.68 kB +0.67% 17.36 kB 17.47 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.development.js +0.70% 91.45 kB 92.08 kB +0.70% 17.39 kB 17.51 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.development.js +0.70% 91.45 kB 92.08 kB +0.70% 17.39 kB 17.51 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.69% 91.96 kB 92.60 kB +0.69% 17.40 kB 17.52 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.69% 91.96 kB 92.60 kB +0.69% 17.40 kB 17.52 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.development.js +0.69% 93.25 kB 93.89 kB +0.68% 17.74 kB 17.86 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.development.js +0.69% 93.25 kB 93.89 kB +0.68% 17.74 kB 17.86 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.68% 94.60 kB 95.24 kB +0.68% 17.86 kB 17.98 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.68% 94.60 kB 95.24 kB +0.68% 17.86 kB 17.98 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.66% 96.34 kB 96.98 kB +0.66% 18.20 kB 18.32 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.66% 96.34 kB 96.98 kB +0.66% 18.20 kB 18.32 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.66% 96.43 kB 97.07 kB +0.66% 18.24 kB 18.36 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.66% 96.43 kB 97.07 kB +0.66% 18.24 kB 18.36 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +0.66% 97.34 kB 97.98 kB +0.66% 18.13 kB 18.25 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +0.66% 97.34 kB 97.98 kB +0.66% 18.13 kB 18.25 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.65% 98.67 kB 99.31 kB +0.66% 18.38 kB 18.51 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.65% 98.67 kB 99.31 kB +0.66% 18.38 kB 18.51 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.53% 145.49 kB 146.26 kB +0.54% 34.12 kB 34.30 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.48% 105.31 kB 105.82 kB +0.46% 20.12 kB 20.22 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.browser.development.js +0.48% 105.66 kB 106.17 kB +0.42% 20.06 kB 20.15 kB
oss-experimental/react-client/cjs/react-client-flight.development.js +0.48% 106.63 kB 107.14 kB +0.49% 19.85 kB 19.94 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +0.47% 107.49 kB 108.00 kB +0.44% 20.51 kB 20.60 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.47% 108.05 kB 108.56 kB +0.47% 20.64 kB 20.74 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.node.development.js +0.47% 108.89 kB 109.40 kB +0.43% 20.82 kB 20.91 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.46% 109.41 kB 109.91 kB +0.43% 20.83 kB 20.92 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-client.edge.development.js +0.46% 110.69 kB 111.20 kB +0.42% 21.19 kB 21.28 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.45% 112.04 kB 112.55 kB +0.42% 21.31 kB 21.40 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.45% 113.79 kB 114.30 kB +0.39% 21.66 kB 21.75 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.45% 113.88 kB 114.39 kB +0.39% 21.70 kB 21.79 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +0.44% 114.79 kB 115.30 kB +0.41% 21.57 kB 21.66 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.44% 116.12 kB 116.63 kB +0.41% 21.83 kB 21.92 kB

Generated by 🚫 dangerJS against 438f110

unstubbable added a commit to unstubbable/react that referenced this pull request Feb 6, 2025
unstubbable added a commit to unstubbable/react that referenced this pull request Feb 7, 2025
@unstubbable unstubbable changed the title Add failing test for client component props deduping [Flight] Resolve deduped references when chunks are blocked on each other Feb 9, 2025
@unstubbable unstubbable marked this pull request as ready for review February 9, 2025 21:14
@unstubbable unstubbable force-pushed the client-component-props-deduping branch from 414c443 to ecb5a8a Compare February 9, 2025 22:59
@unstubbable unstubbable marked this pull request as draft February 9, 2025 23:02
@unstubbable unstubbable marked this pull request as ready for review February 9, 2025 23:04
@@ -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
Copy link
Collaborator

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.

Copy link
Collaborator Author

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 === '';
Copy link
Collaborator

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?

Copy link
Collaborator Author

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:

// 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Specific data/props case causes infinite loading
5 participants