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] Detriplicate Objects #27537

Merged
merged 3 commits into from
Oct 19, 2023
Merged

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented Oct 18, 2023

Now that we no longer support Server Context, we can now deduplicate objects. It's not completely safe for useId but only in the same way as it's not safe if you reuse elements on the client, so it's not a new issue.

This also solves cyclic object references.

The issue is that we prefer to inline objects into a plain JSON format when an object is not going to get reused. In this case the object doesn't have an id. We could potentially serialize a reference to an existing model + a path to it but it bloats the format and complicates the client.

In a smarter flush phase like we have in Fizz we could choose to inline or outline depending on what we've discovered so far before a flush. We can't do that here since we use native stringify. However, even in that solution you might not know that you're going to discover the same object later so it's not perfect deduping anyway.

Instead, I use a heuristic where I mark previously seen objects and if I ever see that object again, then I'll outline it. The idea is that most objects are just going to be emitted once and if it's more than once it's fairly likely you have a shared reference to it somewhere and it might be more than two.

The third object gets deduplicated (or "detriplicated").

It's not a perfect heuristic because when we write the second object we will have already visited all the nested objects inside of it, which causes us to outline every nested object too even those weren't reference more than by that parent. Not sure how to solve for that.

If we for some other reason outline an object such as if it suspends, then it's truly deduplicated since it already has an id.

Outline objects that has been seen at least once before so they can be
deduped.
This won't always work but it'll work if we discover the Map/Set before the key.

The idea is that you'd pass the Map to something like a parent context and
then select out of it with a key passed to a child.
@sebmarkbage sebmarkbage requested review from gnoff and acdlite October 18, 2023 03:40
@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Oct 18, 2023
@react-sizebot
Copy link

Comparing: a419575...b74a718

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.min.js = 174.94 kB 174.94 kB = 54.44 kB 54.44 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 177.06 kB 177.06 kB = 55.12 kB 55.12 kB
facebook-www/ReactDOM-prod.classic.js = 567.28 kB 567.28 kB = 99.85 kB 99.85 kB
facebook-www/ReactDOM-prod.modern.js = 551.14 kB 551.14 kB = 96.94 kB 96.94 kB
oss-experimental/react-server/cjs/react-server-flight.development.js +5.32% 73.74 kB 77.66 kB +4.23% 17.61 kB 18.35 kB
oss-experimental/react-server/cjs/react-server-flight.production.min.js +3.73% 19.09 kB 19.80 kB +2.45% 6.70 kB 6.86 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +3.63% 107.99 kB 111.91 kB +2.85% 25.48 kB 26.21 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +3.54% 110.71 kB 114.63 kB +2.77% 26.50 kB 27.23 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +3.53% 111.12 kB 115.04 kB +2.76% 26.61 kB 27.35 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.development.js +3.50% 116.99 kB 121.09 kB +2.80% 26.87 kB 27.62 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +3.46% 113.19 kB 117.11 kB +2.70% 27.17 kB 27.91 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +3.46% 113.30 kB 117.22 kB +2.71% 27.22 kB 27.96 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js +3.46% 113.40 kB 117.32 kB +2.69% 26.71 kB 27.42 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js +3.42% 119.71 kB 123.81 kB +2.71% 27.61 kB 28.36 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +3.38% 115.83 kB 119.75 kB +2.66% 27.33 kB 28.06 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +3.38% 116.04 kB 119.96 kB +2.68% 27.53 kB 28.27 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +3.31% 118.46 kB 122.38 kB +2.65% 28.20 kB 28.94 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.production.min.js +2.60% 27.77 kB 28.49 kB +1.94% 9.46 kB 9.64 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.min.js +2.51% 28.55 kB 29.27 kB +1.77% 9.60 kB 9.77 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.min.js +2.49% 28.87 kB 29.59 kB +1.60% 9.71 kB 9.87 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.production.min.js +2.49% 28.73 kB 29.44 kB +1.81% 9.71 kB 9.88 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js +2.45% 29.30 kB 30.02 kB +1.67% 9.80 kB 9.96 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.min.js +2.43% 29.50 kB 30.22 kB +1.65% 9.87 kB 10.03 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js +2.42% 29.46 kB 30.18 kB +1.70% 9.92 kB 10.09 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.min.js +2.41% 29.79 kB 30.51 kB +1.64% 10.05 kB 10.22 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.min.js +2.37% 30.30 kB 31.02 kB +1.59% 10.21 kB 10.37 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js +2.35% 30.59 kB 31.31 kB +1.64% 10.24 kB 10.41 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js +2.31% 31.11 kB 31.83 kB +1.57% 10.41 kB 10.58 kB
oss-stable-semver/react-server/cjs/react-server-flight.production.min.js = 17.21 kB 16.85 kB = 6.20 kB 6.02 kB
oss-stable/react-server/cjs/react-server-flight.production.min.js = 17.21 kB 16.85 kB = 6.20 kB 6.02 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js = 111.49 kB 109.09 kB = 26.94 kB 26.12 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js = 111.49 kB 109.09 kB = 26.94 kB 26.12 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js = 109.08 kB 106.67 kB = 26.28 kB 25.45 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js = 109.08 kB 106.67 kB = 26.28 kB 25.45 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js = 108.86 kB 106.45 kB = 26.03 kB 25.23 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js = 108.86 kB 106.45 kB = 26.03 kB 25.23 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js = 106.43 kB 104.03 kB = 25.41 kB 24.62 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js = 106.43 kB 104.03 kB = 25.41 kB 24.62 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js = 105.88 kB 103.47 kB = 25.81 kB 24.97 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js = 105.88 kB 103.47 kB = 25.81 kB 24.97 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js = 105.77 kB 103.36 kB = 25.75 kB 24.93 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js = 105.77 kB 103.36 kB = 25.75 kB 24.93 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js = 111.92 kB 109.34 kB = 26.17 kB 25.31 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js = 111.92 kB 109.34 kB = 26.17 kB 25.31 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js = 103.71 kB 101.30 kB = 25.19 kB 24.37 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js = 103.71 kB 101.30 kB = 25.19 kB 24.37 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js = 103.30 kB 100.89 kB = 25.08 kB 24.25 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js = 103.30 kB 100.89 kB = 25.08 kB 24.25 kB
oss-stable-semver/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.development.js = 109.19 kB 106.61 kB = 25.44 kB 24.59 kB
oss-stable/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.development.js = 109.19 kB 106.61 kB = 25.44 kB 24.59 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js = 101.02 kB 98.61 kB = 24.18 kB 23.40 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js = 101.02 kB 98.61 kB = 24.18 kB 23.40 kB
oss-stable-semver/react-server/cjs/react-server-flight.development.js = 67.00 kB 64.59 kB = 16.45 kB 15.65 kB
oss-stable/react-server/cjs/react-server-flight.development.js = 67.00 kB 64.59 kB = 16.45 kB 15.65 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-experimental/react-server/cjs/react-server-flight.development.js +5.32% 73.74 kB 77.66 kB +4.23% 17.61 kB 18.35 kB
oss-experimental/react-server/cjs/react-server-flight.production.min.js +3.73% 19.09 kB 19.80 kB +2.45% 6.70 kB 6.86 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +3.63% 107.99 kB 111.91 kB +2.85% 25.48 kB 26.21 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +3.54% 110.71 kB 114.63 kB +2.77% 26.50 kB 27.23 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +3.53% 111.12 kB 115.04 kB +2.76% 26.61 kB 27.35 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.development.js +3.50% 116.99 kB 121.09 kB +2.80% 26.87 kB 27.62 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +3.46% 113.19 kB 117.11 kB +2.70% 27.17 kB 27.91 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +3.46% 113.30 kB 117.22 kB +2.71% 27.22 kB 27.96 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js +3.46% 113.40 kB 117.32 kB +2.69% 26.71 kB 27.42 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js +3.42% 119.71 kB 123.81 kB +2.71% 27.61 kB 28.36 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +3.38% 115.83 kB 119.75 kB +2.66% 27.33 kB 28.06 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +3.38% 116.04 kB 119.96 kB +2.68% 27.53 kB 28.27 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +3.31% 118.46 kB 122.38 kB +2.65% 28.20 kB 28.94 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.production.min.js +2.60% 27.77 kB 28.49 kB +1.94% 9.46 kB 9.64 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.min.js +2.51% 28.55 kB 29.27 kB +1.77% 9.60 kB 9.77 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.min.js +2.49% 28.87 kB 29.59 kB +1.60% 9.71 kB 9.87 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.production.min.js +2.49% 28.73 kB 29.44 kB +1.81% 9.71 kB 9.88 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js +2.45% 29.30 kB 30.02 kB +1.67% 9.80 kB 9.96 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.min.js +2.43% 29.50 kB 30.22 kB +1.65% 9.87 kB 10.03 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js +2.42% 29.46 kB 30.18 kB +1.70% 9.92 kB 10.09 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.min.js +2.41% 29.79 kB 30.51 kB +1.64% 10.05 kB 10.22 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.min.js +2.37% 30.30 kB 31.02 kB +1.59% 10.21 kB 10.37 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js +2.35% 30.59 kB 31.31 kB +1.64% 10.24 kB 10.41 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js +2.31% 31.11 kB 31.83 kB +1.57% 10.41 kB 10.58 kB
oss-stable-semver/react-client/cjs/react-client-flight.production.min.js +1.67% 10.39 kB 10.57 kB +0.87% 4.01 kB 4.04 kB
oss-stable/react-client/cjs/react-client-flight.production.min.js +1.67% 10.39 kB 10.57 kB +0.87% 4.01 kB 4.04 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.min.js +1.67% 10.49 kB 10.67 kB +0.77% 4.01 kB 4.04 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.min.js +1.67% 10.49 kB 10.67 kB +0.77% 4.01 kB 4.04 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.min.js +1.65% 40.72 kB 41.40 kB +1.55% 9.95 kB 10.10 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.min.js +1.65% 40.72 kB 41.40 kB +1.55% 9.95 kB 10.10 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.min.js +1.56% 11.21 kB 11.39 kB +0.79% 4.29 kB 4.33 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.min.js +1.56% 11.21 kB 11.39 kB +0.79% 4.29 kB 4.33 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.min.js +1.54% 11.34 kB 11.51 kB +0.76% 4.33 kB 4.36 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.min.js +1.54% 11.34 kB 11.51 kB +0.76% 4.33 kB 4.36 kB
oss-stable-semver/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.production.min.js +1.52% 11.48 kB 11.65 kB +0.78% 4.39 kB 4.42 kB
oss-stable/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.production.min.js +1.52% 11.48 kB 11.65 kB +0.78% 4.39 kB 4.42 kB
oss-experimental/react-client/cjs/react-client-flight.production.min.js +1.50% 11.58 kB 11.76 kB +0.83% 4.34 kB 4.37 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.production.min.js +1.50% 11.60 kB 11.78 kB +0.72% 4.42 kB 4.45 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.production.min.js +1.50% 11.60 kB 11.78 kB +0.72% 4.42 kB 4.45 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.min.js +1.48% 11.80 kB 11.97 kB +0.83% 4.36 kB 4.39 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.min.js +1.47% 45.81 kB 46.48 kB +1.42% 10.94 kB 11.10 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.min.js +1.42% 12.35 kB 12.53 kB +0.82% 4.64 kB 4.67 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.min.js +1.42% 12.35 kB 12.53 kB +0.82% 4.64 kB 4.67 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.production.min.js +1.40% 12.52 kB 12.69 kB +0.75% 4.64 kB 4.67 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.min.js +1.38% 12.64 kB 12.82 kB +0.73% 4.67 kB 4.71 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js +1.37% 12.73 kB 12.91 kB +0.83% 4.81 kB 4.85 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js +1.37% 12.73 kB 12.91 kB +0.83% 4.81 kB 4.85 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.production.min.js +1.37% 12.73 kB 12.91 kB +0.85% 4.81 kB 4.85 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.production.min.js +1.37% 12.73 kB 12.91 kB +0.85% 4.81 kB 4.85 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.production.min.js +1.36% 12.79 kB 12.96 kB +0.80% 4.74 kB 4.78 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.production.min.js +1.35% 12.91 kB 13.08 kB +0.79% 4.78 kB 4.82 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.min.js +1.34% 13.06 kB 13.23 kB +0.87% 4.93 kB 4.97 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.min.js +1.34% 13.06 kB 13.23 kB +0.87% 4.93 kB 4.97 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.min.js +1.34% 13.06 kB 13.24 kB +0.89% 4.94 kB 4.98 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.min.js +1.34% 13.06 kB 13.24 kB +0.89% 4.94 kB 4.98 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.min.js +1.31% 13.28 kB 13.45 kB +0.68% 5.01 kB 5.05 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.min.js +1.31% 13.28 kB 13.45 kB +0.68% 5.01 kB 5.05 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.min.js +1.31% 13.29 kB 13.46 kB +0.70% 5.02 kB 5.06 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.min.js +1.31% 13.29 kB 13.46 kB +0.70% 5.02 kB 5.06 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.min.js +1.29% 13.67 kB 13.85 kB +0.78% 5.00 kB 5.04 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +1.25% 53.13 kB 53.80 kB +1.13% 12.88 kB 13.03 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +1.25% 53.13 kB 53.80 kB +1.13% 12.88 kB 13.03 kB
oss-stable-semver/react-client/cjs/react-client-flight.development.js +1.25% 53.18 kB 53.85 kB +1.12% 13.27 kB 13.41 kB
oss-stable/react-client/cjs/react-client-flight.development.js +1.25% 53.18 kB 53.85 kB +1.12% 13.27 kB 13.41 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js +1.25% 14.06 kB 14.23 kB +0.81% 5.18 kB 5.22 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.production.min.js +1.25% 14.06 kB 14.23 kB +0.81% 5.18 kB 5.22 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +1.25% 53.33 kB 54.00 kB +1.15% 12.94 kB 13.09 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +1.25% 53.33 kB 54.00 kB +1.15% 12.94 kB 13.09 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.production.min.js +1.22% 14.38 kB 14.55 kB +0.70% 5.29 kB 5.33 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.min.js +1.22% 14.39 kB 14.56 kB +0.75% 5.30 kB 5.34 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.production.min.js +1.19% 14.59 kB 14.76 kB +0.75% 5.37 kB 5.41 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.min.js +1.19% 14.60 kB 14.77 kB +0.74% 5.38 kB 5.42 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +1.18% 56.58 kB 57.25 kB +1.09% 13.92 kB 14.07 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +1.18% 56.58 kB 57.25 kB +1.09% 13.92 kB 14.07 kB
oss-stable-semver/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.development.js +1.17% 60.18 kB 60.88 kB +1.06% 14.13 kB 14.28 kB
oss-stable/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.development.js +1.17% 60.18 kB 60.88 kB +1.06% 14.13 kB 14.28 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +1.17% 57.09 kB 57.76 kB +1.06% 14.09 kB 14.24 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +1.17% 57.09 kB 57.76 kB +1.06% 14.09 kB 14.24 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js +1.16% 60.72 kB 61.42 kB +1.04% 14.31 kB 14.46 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js +1.16% 60.72 kB 61.42 kB +1.04% 14.31 kB 14.46 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +1.14% 58.18 kB 58.84 kB +1.10% 13.88 kB 14.03 kB
oss-experimental/react-client/cjs/react-client-flight.development.js +1.14% 58.23 kB 58.90 kB +1.09% 14.27 kB 14.42 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +1.14% 58.38 kB 59.05 kB +1.10% 13.94 kB 14.10 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +1.12% 59.40 kB 60.07 kB +1.05% 14.53 kB 14.68 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +1.12% 59.40 kB 60.07 kB +1.05% 14.53 kB 14.68 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +1.09% 61.19 kB 61.85 kB +1.02% 15.07 kB 15.22 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +1.09% 61.19 kB 61.85 kB +1.02% 15.07 kB 15.22 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +1.09% 61.22 kB 61.89 kB +1.01% 15.10 kB 15.25 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +1.09% 61.22 kB 61.89 kB +1.01% 15.10 kB 15.25 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +1.08% 61.63 kB 62.30 kB +1.06% 14.92 kB 15.07 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +1.07% 62.14 kB 62.81 kB +1.03% 15.09 kB 15.24 kB
oss-experimental/react-server-dom-turbopack/umd/react-server-dom-turbopack-client.browser.development.js +1.07% 65.53 kB 66.23 kB +0.98% 15.15 kB 15.30 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +1.06% 62.62 kB 63.29 kB +0.98% 15.46 kB 15.62 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +1.06% 62.62 kB 63.29 kB +0.98% 15.46 kB 15.62 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +1.06% 62.65 kB 63.31 kB +0.99% 15.51 kB 15.66 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +1.06% 62.65 kB 63.31 kB +0.99% 15.51 kB 15.66 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js +1.06% 66.07 kB 66.77 kB +0.97% 15.33 kB 15.48 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +1.05% 63.29 kB 63.96 kB +0.97% 15.60 kB 15.75 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +1.05% 63.29 kB 63.96 kB +0.97% 15.60 kB 15.75 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +1.05% 63.32 kB 63.98 kB +0.98% 15.64 kB 15.79 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +1.05% 63.32 kB 63.98 kB +0.98% 15.64 kB 15.79 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +1.03% 64.45 kB 65.12 kB +0.98% 15.55 kB 15.70 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +1.01% 66.23 kB 66.90 kB +0.96% 16.09 kB 16.24 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +1.01% 66.27 kB 66.93 kB +0.96% 16.12 kB 16.27 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +0.98% 67.67 kB 68.33 kB +0.93% 16.48 kB 16.64 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +0.98% 67.69 kB 68.36 kB +0.93% 16.53 kB 16.68 kB
oss-experimental/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +0.97% 68.34 kB 69.00 kB +0.94% 16.62 kB 16.77 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +0.97% 68.36 kB 69.03 kB +0.94% 16.66 kB 16.82 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js = 29.20 kB 28.84 kB = 9.91 kB 9.73 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js = 29.20 kB 28.84 kB = 9.91 kB 9.73 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js = 28.68 kB 28.32 kB = 9.75 kB 9.58 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js = 28.68 kB 28.32 kB = 9.75 kB 9.58 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.min.js = 28.39 kB 28.03 kB = 9.70 kB 9.52 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.min.js = 28.39 kB 28.03 kB = 9.70 kB 9.52 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.min.js = 27.88 kB 27.53 kB = 9.55 kB 9.37 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.min.js = 27.88 kB 27.53 kB = 9.55 kB 9.37 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js = 27.33 kB 26.97 kB = 9.29 kB 9.12 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js = 27.33 kB 26.97 kB = 9.29 kB 9.12 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.min.js = 27.53 kB 27.17 kB = 9.35 kB 9.19 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.min.js = 27.53 kB 27.17 kB = 9.35 kB 9.19 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js = 27.49 kB 27.13 kB = 9.41 kB 9.24 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js = 27.49 kB 27.13 kB = 9.41 kB 9.24 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.min.js = 26.90 kB 26.54 kB = 9.19 kB 9.03 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.min.js = 26.90 kB 26.54 kB = 9.19 kB 9.03 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.min.js = 26.58 kB 26.22 kB = 9.09 kB 8.93 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.min.js = 26.58 kB 26.22 kB = 9.09 kB 8.93 kB
oss-stable-semver/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.production.min.js = 26.76 kB 26.40 kB = 9.20 kB 9.01 kB
oss-stable/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.production.min.js = 26.76 kB 26.40 kB = 9.20 kB 9.01 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-server.node.production.min.js = 25.86 kB 25.50 kB = 8.97 kB 8.78 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-server.node.production.min.js = 25.86 kB 25.50 kB = 8.97 kB 8.78 kB
oss-stable-semver/react-server/cjs/react-server-flight.production.min.js = 17.21 kB 16.85 kB = 6.20 kB 6.02 kB
oss-stable/react-server/cjs/react-server-flight.production.min.js = 17.21 kB 16.85 kB = 6.20 kB 6.02 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js = 111.49 kB 109.09 kB = 26.94 kB 26.12 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js = 111.49 kB 109.09 kB = 26.94 kB 26.12 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js = 109.08 kB 106.67 kB = 26.28 kB 25.45 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js = 109.08 kB 106.67 kB = 26.28 kB 25.45 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js = 108.86 kB 106.45 kB = 26.03 kB 25.23 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js = 108.86 kB 106.45 kB = 26.03 kB 25.23 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js = 106.43 kB 104.03 kB = 25.41 kB 24.62 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js = 106.43 kB 104.03 kB = 25.41 kB 24.62 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js = 105.88 kB 103.47 kB = 25.81 kB 24.97 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js = 105.88 kB 103.47 kB = 25.81 kB 24.97 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js = 105.77 kB 103.36 kB = 25.75 kB 24.93 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js = 105.77 kB 103.36 kB = 25.75 kB 24.93 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js = 111.92 kB 109.34 kB = 26.17 kB 25.31 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js = 111.92 kB 109.34 kB = 26.17 kB 25.31 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js = 103.71 kB 101.30 kB = 25.19 kB 24.37 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js = 103.71 kB 101.30 kB = 25.19 kB 24.37 kB
oss-stable-semver/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js = 103.30 kB 100.89 kB = 25.08 kB 24.25 kB
oss-stable/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js = 103.30 kB 100.89 kB = 25.08 kB 24.25 kB
oss-stable-semver/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.development.js = 109.19 kB 106.61 kB = 25.44 kB 24.59 kB
oss-stable/react-server-dom-turbopack/umd/react-server-dom-turbopack-server.browser.development.js = 109.19 kB 106.61 kB = 25.44 kB 24.59 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js = 101.02 kB 98.61 kB = 24.18 kB 23.40 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js = 101.02 kB 98.61 kB = 24.18 kB 23.40 kB
oss-stable-semver/react-server/cjs/react-server-flight.development.js = 67.00 kB 64.59 kB = 16.45 kB 15.65 kB
oss-stable/react-server/cjs/react-server-flight.development.js = 67.00 kB 64.59 kB = 16.45 kB 15.65 kB

Generated by 🚫 dangerJS against b74a718

@sebmarkbage
Copy link
Collaborator Author

Another possible heuristic could be to always outline objects one level below the props object of client components. The idea is that JSX is often not duplicated by reference and creating large JSX trees is where inlining is better.

Other than the style object, you don't typically pass deduped props to host elements.

Passing flat values to client components is generally better so it's not super common that you should pass rich objects to client components in the first place. It also might have semantic meaning if you do. So eagerly outlining them might not be as big of a cost.

Copy link
Collaborator

@sophiebits sophiebits left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is it not safe to reuse elements on the client?

@@ -810,12 +822,36 @@ function serializeMap(
request: Request,
map: Map<ReactClientValue, ReactClientValue>,
): string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maps with object keys (or Sets of objects) seems like an interesting case where the object identity is virtually guaranteed to be semantic. Should we even allow that if there's no guarantee on it matching other places where that object is sent down (including other Map/Set instances)?

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 rationalize it is that you can or cannot use it the same way you can use it in React on the client. If you create a Map and keys during render and pass it around, it depends on if those rerender together whether you can use that pattern or not.

In normal usage like if you create a Map in a parent and then pass ids into that Map to the children to refer to that map, as long as they get recreated together they'll flow downwards together too to get updated. Assuming you follow the updating rules of React.

Similarly, a second request updating the Map would need to do the same.

@sebmarkbage
Copy link
Collaborator Author

sebmarkbage commented Oct 18, 2023

When is it not safe to reuse elements on the client?

"use client";
function ClientComponent({ icon }) {
  return items.map(i => <div>
    {icon}
  </div>;
}
function SharedComponent() {
  return <div id={useId()} />;
}
function ServerComponent() {
  return <ClientComponent icon={<SharedComponent />} />
}

All the icons in the shared component would share the same id in this case which they wouldn't on the client. This change expands that to another case but it's the same principle.

@sophiebits
Copy link
Collaborator

It's not completely safe for useId but only in the same way as it's not safe if you reuse elements on the client

I understand why this isn’t safe for useId but I don’t understand what existing behavior has a similar problem.

@sebmarkbage
Copy link
Collaborator Author

My example is showing the problem with existing behavior. The Client component is only rendered once on the server. The loop happens client side which reuses the result of rendering SharedComponent which has only been rendered once.

@gnoff
Copy link
Collaborator

gnoff commented Oct 18, 2023

Another possible heuristic could be to always outline objects one level below the props object of client components. The idea is that JSX is often not duplicated by reference and creating large JSX trees is where inlining is better.

This is kind of how I was imagining it would work

@acdlite
Copy link
Collaborator

acdlite commented Oct 19, 2023

You could also outline anything that’s the result of a cache call. That would be nice because we’d then have a way to opt in explicitly for cases not covered by the other heuristics.

@@ -379,9 +402,13 @@ function initializeModelChunk<T>(chunk: ResolvedModelChunk<T>): void {
blockedChunk.value = null;
blockedChunk.reason = null;
} else {
const resolveListeners = cyclicChunk.value;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when is this not null?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discovering a cycle doesn't add to the .deps so we might end up at zero. The inner property listens for this model to complete so that it can update its property to set the cycle.

@gnoff
Copy link
Collaborator

gnoff commented Oct 19, 2023

Throwing crazy ideas out here

maybe we put a special empty chunk at the start of a series of chunks representing an object which uniquely identifies an object. When we see this during flush we store how many bytes into the stream this object appears. We also stored how long the object chunks are when we encoded it. Later when we encounter that object again we serialize a byte offset and length value.

On the client when we encounter this offset + length we reparse those bytes and cache the object. On a second encounter to this offset + length we look the object up in a cache using the byte offset.

It's unfortunate that we'd need to check each chunk to see if it is a marker chunk but maybe it is worth it for the compactness you get on the wire

@sebmarkbage sebmarkbage merged commit f172fa7 into facebook:main Oct 19, 2023
2 checks passed
github-actions bot pushed a commit that referenced this pull request Oct 19, 2023
Now that we no longer support Server Context, we can now deduplicate
objects. It's not completely safe for useId but only in the same way as
it's not safe if you reuse elements on the client, so it's not a new
issue.

This also solves cyclic object references.

The issue is that we prefer to inline objects into a plain JSON format
when an object is not going to get reused. In this case the object
doesn't have an id. We could potentially serialize a reference to an
existing model + a path to it but it bloats the format and complicates
the client.

In a smarter flush phase like we have in Fizz we could choose to inline
or outline depending on what we've discovered so far before a flush. We
can't do that here since we use native stringify. However, even in that
solution you might not know that you're going to discover the same
object later so it's not perfect deduping anyway.

Instead, I use a heuristic where I mark previously seen objects and if I
ever see that object again, then I'll outline it. The idea is that most
objects are just going to be emitted once and if it's more than once
it's fairly likely you have a shared reference to it somewhere and it
might be more than two.

The third object gets deduplicated (or "detriplicated").

It's not a perfect heuristic because when we write the second object we
will have already visited all the nested objects inside of it, which
causes us to outline every nested object too even those weren't
reference more than by that parent. Not sure how to solve for that.

If we for some other reason outline an object such as if it suspends,
then it's truly deduplicated since it already has an id.

DiffTrain build for [f172fa7](f172fa7)
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
Now that we no longer support Server Context, we can now deduplicate
objects. It's not completely safe for useId but only in the same way as
it's not safe if you reuse elements on the client, so it's not a new
issue.

This also solves cyclic object references.

The issue is that we prefer to inline objects into a plain JSON format
when an object is not going to get reused. In this case the object
doesn't have an id. We could potentially serialize a reference to an
existing model + a path to it but it bloats the format and complicates
the client.

In a smarter flush phase like we have in Fizz we could choose to inline
or outline depending on what we've discovered so far before a flush. We
can't do that here since we use native stringify. However, even in that
solution you might not know that you're going to discover the same
object later so it's not perfect deduping anyway.

Instead, I use a heuristic where I mark previously seen objects and if I
ever see that object again, then I'll outline it. The idea is that most
objects are just going to be emitted once and if it's more than once
it's fairly likely you have a shared reference to it somewhere and it
might be more than two.

The third object gets deduplicated (or "detriplicated").

It's not a perfect heuristic because when we write the second object we
will have already visited all the nested objects inside of it, which
causes us to outline every nested object too even those weren't
reference more than by that parent. Not sure how to solve for that.

If we for some other reason outline an object such as if it suspends,
then it's truly deduplicated since it already has an id.
bigfootjon pushed a commit that referenced this pull request Apr 18, 2024
Now that we no longer support Server Context, we can now deduplicate
objects. It's not completely safe for useId but only in the same way as
it's not safe if you reuse elements on the client, so it's not a new
issue.

This also solves cyclic object references.

The issue is that we prefer to inline objects into a plain JSON format
when an object is not going to get reused. In this case the object
doesn't have an id. We could potentially serialize a reference to an
existing model + a path to it but it bloats the format and complicates
the client.

In a smarter flush phase like we have in Fizz we could choose to inline
or outline depending on what we've discovered so far before a flush. We
can't do that here since we use native stringify. However, even in that
solution you might not know that you're going to discover the same
object later so it's not perfect deduping anyway.

Instead, I use a heuristic where I mark previously seen objects and if I
ever see that object again, then I'll outline it. The idea is that most
objects are just going to be emitted once and if it's more than once
it's fairly likely you have a shared reference to it somewhere and it
might be more than two.

The third object gets deduplicated (or "detriplicated").

It's not a perfect heuristic because when we write the second object we
will have already visited all the nested objects inside of it, which
causes us to outline every nested object too even those weren't
reference more than by that parent. Not sure how to solve for that.

If we for some other reason outline an object such as if it suspends,
then it's truly deduplicated since it already has an id.

DiffTrain build for commit f172fa7.
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.

6 participants