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] Add Serialization of Typed Arrays / ArrayBuffer / DataView #26954

Merged
merged 4 commits into from
Jun 29, 2023

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented Jun 15, 2023

This uses the same mechanism as large strings to encode chunks of length based binary data in the RSC payload behind a flag.

I introduce a new BinaryChunk type that's specific to each stream and ways to convert into it. That's because we sometimes need all chunks to be Uint8Array for the output, even if the source is another array buffer view, and sometimes we need to clone it before transferring.

Each type of typed array is its own row tag. This lets us ensure that the instance is directly in the right format in the cached entry instead of creating a wrapper at each reference. Ideally this is also how Map/Set should work but those are lazy which complicates that approach a bit.

We assume both server and client use little-endian for now. If we want to support other modes, we'd convert it to/from little-endian so that the transfer protocol is always little-endian. That way the common clients can be the fastest possible.

So far this only implements Server to Client. Still need to implement Client to Server for parity.

NOTE: This is the first time we make RSC effectively a binary format. This is not compatible with existing SSR techniques which serialize the stream as unicode in the HTML. To be compatible, those implementations would have to use base64 or something like that. Which is what we'll do when we move this technique to be built-in to Fizz.

@sebmarkbage sebmarkbage requested review from sophiebits and gnoff June 15, 2023 03:54
@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Jun 15, 2023
@react-sizebot
Copy link

react-sizebot commented Jun 15, 2023

Comparing: 2153a29...287cf4a

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 = 164.32 kB 164.32 kB = 51.75 kB 51.75 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 171.73 kB 171.73 kB = 53.97 kB 53.97 kB
facebook-www/ReactDOM-prod.classic.js = 568.20 kB 568.20 kB = 100.14 kB 100.14 kB
facebook-www/ReactDOM-prod.modern.js = 552.00 kB 552.00 kB = 97.29 kB 97.29 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.min.js +11.19% 39.84 kB 44.30 kB +9.64% 9.89 kB 10.85 kB
oss-experimental/react-client/cjs/react-client-flight.production.min.js +10.86% 9.17 kB 10.17 kB +8.23% 3.61 kB 3.91 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.min.js +9.97% 10.26 kB 11.28 kB +7.87% 3.99 kB 4.31 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.min.js +9.81% 10.31 kB 11.32 kB +7.67% 4.03 kB 4.34 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.min.js +9.72% 10.41 kB 11.42 kB +7.64% 4.04 kB 4.35 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js +9.60% 10.66 kB 11.68 kB +7.45% 4.16 kB 4.47 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.production.min.js +9.56% 10.58 kB 11.59 kB +7.59% 4.12 kB 4.44 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.min.js +9.31% 10.98 kB 12.01 kB +7.25% 4.29 kB 4.60 kB
oss-experimental/react-client/cjs/react-client-flight.development.js +9.23% 48.25 kB 52.70 kB +7.87% 12.05 kB 13.00 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.min.js +9.00% 11.24 kB 12.25 kB +7.11% 4.38 kB 4.69 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +8.65% 51.46 kB 55.92 kB +7.55% 12.56 kB 13.51 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +8.57% 51.94 kB 56.39 kB +7.48% 12.63 kB 13.57 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +8.55% 52.05 kB 56.50 kB +7.33% 12.72 kB 13.66 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +8.54% 52.10 kB 56.55 kB +7.44% 12.69 kB 13.63 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js +8.50% 55.39 kB 60.10 kB +7.41% 12.92 kB 13.88 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +8.44% 52.75 kB 57.20 kB +7.45% 12.87 kB 13.83 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +8.25% 53.99 kB 58.44 kB +7.23% 13.26 kB 14.22 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +8.14% 54.71 kB 59.16 kB +7.15% 13.41 kB 14.37 kB
oss-experimental/react-server/cjs/react-server-flight.production.min.js +4.57% 16.33 kB 17.08 kB +3.41% 5.87 kB 6.07 kB
oss-experimental/react-server/cjs/react-server-flight.development.js +3.77% 67.02 kB 69.55 kB +2.58% 16.12 kB 16.54 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js +3.47% 22.27 kB 23.04 kB +2.47% 7.83 kB 8.02 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js +3.44% 22.47 kB 23.25 kB +2.45% 7.95 kB 8.14 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.min.js +3.42% 22.57 kB 23.34 kB +2.43% 7.93 kB 8.12 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +3.38% 92.28 kB 95.39 kB +2.97% 22.27 kB 22.94 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +3.36% 92.69 kB 95.80 kB +2.99% 22.39 kB 23.05 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js +3.35% 97.59 kB 100.86 kB +2.82% 22.64 kB 23.28 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.production.min.js +3.06% 23.35 kB 24.06 kB +2.24% 8.14 kB 8.33 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js +3.04% 23.53 kB 24.24 kB +2.20% 8.24 kB 8.42 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js +2.98% 24.06 kB 24.77 kB +2.12% 8.41 kB 8.59 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.80% 94.74 kB 97.39 kB +2.21% 22.57 kB 23.07 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +2.76% 96.00 kB 98.66 kB +2.18% 22.90 kB 23.39 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +2.71% 98.05 kB 100.70 kB +2.10% 23.48 kB 23.97 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-dom-esm/esm/react-server-dom-esm-client.browser.production.min.js +11.19% 39.84 kB 44.30 kB +9.64% 9.89 kB 10.85 kB
oss-experimental/react-client/cjs/react-client-flight.production.min.js +10.86% 9.17 kB 10.17 kB +8.23% 3.61 kB 3.91 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.min.js +9.97% 10.26 kB 11.28 kB +7.87% 3.99 kB 4.31 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.min.js +9.81% 10.31 kB 11.32 kB +7.67% 4.03 kB 4.34 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.min.js +9.72% 10.41 kB 11.42 kB +7.64% 4.04 kB 4.35 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js +9.60% 10.66 kB 11.68 kB +7.45% 4.16 kB 4.47 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.production.min.js +9.56% 10.58 kB 11.59 kB +7.59% 4.12 kB 4.44 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.min.js +9.31% 10.98 kB 12.01 kB +7.25% 4.29 kB 4.60 kB
oss-experimental/react-client/cjs/react-client-flight.development.js +9.23% 48.25 kB 52.70 kB +7.87% 12.05 kB 13.00 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.production.min.js +9.00% 11.24 kB 12.25 kB +7.11% 4.38 kB 4.69 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +8.65% 51.46 kB 55.92 kB +7.55% 12.56 kB 13.51 kB
oss-experimental/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +8.57% 51.94 kB 56.39 kB +7.48% 12.63 kB 13.57 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +8.55% 52.05 kB 56.50 kB +7.33% 12.72 kB 13.66 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +8.54% 52.10 kB 56.55 kB +7.44% 12.69 kB 13.63 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js +8.50% 55.39 kB 60.10 kB +7.41% 12.92 kB 13.88 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +8.44% 52.75 kB 57.20 kB +7.45% 12.87 kB 13.83 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +8.25% 53.99 kB 58.44 kB +7.23% 13.26 kB 14.22 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +8.14% 54.71 kB 59.16 kB +7.15% 13.41 kB 14.37 kB
oss-experimental/react-server/cjs/react-server-flight.production.min.js +4.57% 16.33 kB 17.08 kB +3.41% 5.87 kB 6.07 kB
oss-experimental/react-server/cjs/react-server-flight.development.js +3.77% 67.02 kB 69.55 kB +2.58% 16.12 kB 16.54 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js +3.47% 22.27 kB 23.04 kB +2.47% 7.83 kB 8.02 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js +3.44% 22.47 kB 23.25 kB +2.45% 7.95 kB 8.14 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.min.js +3.42% 22.57 kB 23.34 kB +2.43% 7.93 kB 8.12 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +3.38% 92.28 kB 95.39 kB +2.97% 22.27 kB 22.94 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +3.36% 92.69 kB 95.80 kB +2.99% 22.39 kB 23.05 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js +3.35% 97.59 kB 100.86 kB +2.82% 22.64 kB 23.28 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.production.min.js +3.06% 23.35 kB 24.06 kB +2.24% 8.14 kB 8.33 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.min.js +3.04% 23.53 kB 24.24 kB +2.20% 8.24 kB 8.42 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js +2.98% 24.06 kB 24.77 kB +2.12% 8.41 kB 8.59 kB
oss-experimental/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development.js +2.80% 94.74 kB 97.39 kB +2.21% 22.57 kB 23.07 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +2.76% 96.00 kB 98.66 kB +2.18% 22.90 kB 23.39 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +2.71% 98.05 kB 100.70 kB +2.10% 23.48 kB 23.97 kB
oss-stable-semver/react-server/cjs/react-server-flight.production.min.js +0.44% 16.33 kB 16.40 kB +0.34% 5.87 kB 5.89 kB
oss-stable/react-server/cjs/react-server-flight.production.min.js +0.44% 16.33 kB 16.40 kB +0.34% 5.87 kB 5.89 kB
oss-stable-semver/react-server/cjs/react-server.production.min.js +0.27% 24.97 kB 25.04 kB +0.20% 8.49 kB 8.51 kB
oss-stable/react-server/cjs/react-server.production.min.js +0.27% 24.97 kB 25.04 kB +0.20% 8.49 kB 8.51 kB
oss-experimental/react-server/cjs/react-server.production.min.js +0.27% 25.39 kB 25.46 kB +0.20% 8.64 kB 8.66 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.min.js +0.26% 39.84 kB 39.95 kB +0.60% 9.89 kB 9.95 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production.min.js +0.26% 39.84 kB 39.95 kB +0.60% 9.89 kB 9.95 kB
oss-stable-semver/react-client/cjs/react-client-flight.development.js +0.22% 48.25 kB 48.36 kB +0.44% 12.05 kB 12.10 kB
oss-stable/react-client/cjs/react-client-flight.development.js +0.22% 48.25 kB 48.36 kB +0.44% 12.05 kB 12.10 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.20% 51.46 kB 51.57 kB +0.41% 12.56 kB 12.62 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development.js +0.20% 51.46 kB 51.57 kB +0.41% 12.56 kB 12.62 kB
oss-stable-semver/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.20% 51.94 kB 52.04 kB +0.44% 12.63 kB 12.68 kB
oss-stable/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development.js +0.20% 51.94 kB 52.04 kB +0.44% 12.63 kB 12.68 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.20% 52.05 kB 52.16 kB +0.44% 12.72 kB 12.78 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +0.20% 52.05 kB 52.16 kB +0.44% 12.72 kB 12.78 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.20% 52.10 kB 52.21 kB +0.43% 12.69 kB 12.74 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development.js +0.20% 52.10 kB 52.21 kB +0.43% 12.69 kB 12.74 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.min.js = 10.41 kB 10.39 kB = 4.04 kB 4.03 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production.min.js = 10.41 kB 10.39 kB = 4.04 kB 4.03 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.min.js = 10.31 kB 10.29 kB = 4.03 kB 4.02 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.production.min.js = 10.31 kB 10.29 kB = 4.03 kB 4.02 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.min.js = 10.98 kB 10.96 kB = 4.29 kB 4.28 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.production.min.js = 10.98 kB 10.96 kB = 4.29 kB 4.28 kB
oss-stable-semver/react-client/cjs/react-client-flight.production.min.js = 9.17 kB 9.15 kB = 3.61 kB 3.60 kB
oss-stable/react-client/cjs/react-client-flight.production.min.js = 9.17 kB 9.15 kB = 3.61 kB 3.60 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js = 10.66 kB 10.63 kB = 4.16 kB 4.15 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.production.min.js = 10.66 kB 10.63 kB = 4.16 kB 4.15 kB
oss-stable-semver/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.min.js = 10.26 kB 10.23 kB = 3.99 kB 3.98 kB
oss-stable/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production.min.js = 10.26 kB 10.23 kB = 3.99 kB 3.98 kB

Generated by 🚫 dangerJS against 287cf4a

@sebmarkbage sebmarkbage force-pushed the flightbinary branch 2 times, most recently from dfdc0e0 to 729759d Compare June 15, 2023 04:19
This lets us have different environments operate on different types, such
as passing the raw typed array when possible.
@sebmarkbage sebmarkbage merged commit d9c3331 into facebook:main Jun 29, 2023
EdisonVan pushed a commit to EdisonVan/react that referenced this pull request Apr 15, 2024
…acebook#26954)

This uses the same mechanism as [large
strings](facebook#26932) to encode chunks
of length based binary data in the RSC payload behind a flag.

I introduce a new BinaryChunk type that's specific to each stream and
ways to convert into it. That's because we sometimes need all chunks to
be Uint8Array for the output, even if the source is another array buffer
view, and sometimes we need to clone it before transferring.

Each type of typed array is its own row tag. This lets us ensure that
the instance is directly in the right format in the cached entry instead
of creating a wrapper at each reference. Ideally this is also how
Map/Set should work but those are lazy which complicates that approach a
bit.

We assume both server and client use little-endian for now. If we want
to support other modes, we'd convert it to/from little-endian so that
the transfer protocol is always little-endian. That way the common
clients can be the fastest possible.

So far this only implements Server to Client. Still need to implement
Client to Server for parity.

NOTE: This is the first time we make RSC effectively a binary format.
This is not compatible with existing SSR techniques which serialize the
stream as unicode in the HTML. To be compatible, those implementations
would have to use base64 or something like that. Which is what we'll do
when we move this technique to be built-in to Fizz.
bigfootjon pushed a commit that referenced this pull request Apr 18, 2024
…26954)

This uses the same mechanism as [large
strings](#26932) to encode chunks
of length based binary data in the RSC payload behind a flag.

I introduce a new BinaryChunk type that's specific to each stream and
ways to convert into it. That's because we sometimes need all chunks to
be Uint8Array for the output, even if the source is another array buffer
view, and sometimes we need to clone it before transferring.

Each type of typed array is its own row tag. This lets us ensure that
the instance is directly in the right format in the cached entry instead
of creating a wrapper at each reference. Ideally this is also how
Map/Set should work but those are lazy which complicates that approach a
bit.

We assume both server and client use little-endian for now. If we want
to support other modes, we'd convert it to/from little-endian so that
the transfer protocol is always little-endian. That way the common
clients can be the fastest possible.

So far this only implements Server to Client. Still need to implement
Client to Server for parity.

NOTE: This is the first time we make RSC effectively a binary format.
This is not compatible with existing SSR techniques which serialize the
stream as unicode in the HTML. To be compatible, those implementations
would have to use base64 or something like that. Which is what we'll do
when we move this technique to be built-in to Fizz.

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

4 participants