Skip to content

[Flight] Lazily parse models and allow any value to suspend#18476

Merged
sebmarkbage merged 7 commits into
facebook:masterfrom
sebmarkbage:lazychunk
Apr 3, 2020
Merged

[Flight] Lazily parse models and allow any value to suspend#18476
sebmarkbage merged 7 commits into
facebook:masterfrom
sebmarkbage:lazychunk

Conversation

@sebmarkbage
Copy link
Copy Markdown
Contributor

There's a bunch of refactoring here but there are two key features that this unlocks:

  1. We now parse the model lazily instead of when it arrives. This improves initial perf since not all models will actually be used during initial render, and it allows this work to be properly scheduled along with other React work. This also allow us to suspend when parsing a model. We can use this to allow arbitrary values to suspend. I.e. any value can be replaced with a "reference" (e.g. "$123") and if it's not available, the whole model suspends. Instead of getters/proxies. Blocks are special in that they can suspend at the React component level and therefore don't suspend the whole model.
  2. This in turn lets us emit incomplete React elements as future references. Therefore, server components can now suspend and then fill in the content later.

@sebmarkbage sebmarkbage requested a review from gaearon April 3, 2020 05:08
@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Apr 3, 2020
@codesandbox-ci
Copy link
Copy Markdown

codesandbox-ci Bot commented Apr 3, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit f332493:

Sandbox Source
naughty-leavitt-0iu5n Configuration

@sebmarkbage sebmarkbage force-pushed the lazychunk branch 2 times, most recently from 8a75c38 to 38590c5 Compare April 3, 2020 05:21
@sizebot
Copy link
Copy Markdown

sizebot commented Apr 3, 2020

Details of bundled changes.

Comparing: 59fd09c...f332493

react-flight-dom-webpack

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-flight-dom-webpack-server.node.production.min.js 🔺+9.3% 🔺+2.1% 3.43 KB 3.74 KB 1.57 KB 1.6 KB NODE_PROD
react-flight-dom-webpack.development.js +6.3% +7.4% 15.36 KB 16.33 KB 4.31 KB 4.63 KB UMD_DEV
react-flight-dom-webpack.production.min.js -1.2% 🔺+2.5% 3.7 KB 3.65 KB 1.65 KB 1.69 KB UMD_PROD
react-flight-dom-webpack-server-runtime.development.js 0.0% +0.1% 2.54 KB 2.54 KB 925 B 926 B NODE_DEV
react-flight-dom-webpack-plugin.development.js 0.0% -0.8% 669 B 669 B 396 B 393 B NODE_DEV
react-flight-dom-webpack-plugin.production.min.js 0.0% 🔺+0.4% 383 B 383 B 282 B 283 B NODE_PROD
react-flight-dom-webpack-server.node.development.js +8.1% +3.9% 11.78 KB 12.74 KB 3.52 KB 3.65 KB NODE_DEV
react-flight-dom-webpack.development.js +6.5% +7.5% 14.26 KB 15.19 KB 4.2 KB 4.52 KB NODE_DEV
react-flight-dom-webpack-server.browser.development.js +8.6% +4.1% 11.74 KB 12.74 KB 3.36 KB 3.49 KB UMD_DEV
react-flight-dom-webpack.production.min.js -1.2% 🔺+3.3% 3.52 KB 3.47 KB 1.55 KB 1.6 KB NODE_PROD
react-flight-dom-webpack-server.browser.production.min.js 🔺+9.1% 🔺+2.1% 3.44 KB 3.75 KB 1.62 KB 1.66 KB UMD_PROD
react-flight-dom-webpack-server.browser.development.js +8.8% +4.2% 10.84 KB 11.79 KB 3.25 KB 3.39 KB NODE_DEV
react-flight-dom-webpack-server.browser.production.min.js 🔺+9.8% 🔺+2.0% 3.25 KB 3.57 KB 1.54 KB 1.57 KB NODE_PROD

react-flight-dom-relay

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactFlightDOMRelayServer-dev.js +8.8% +4.5% 11.02 KB 11.99 KB 3.2 KB 3.34 KB FB_WWW_DEV
ReactFlightDOMRelayServer-prod.js 🔺+9.2% 🔺+5.8% 7.6 KB 8.3 KB 2.22 KB 2.35 KB FB_WWW_PROD
ReactFlightDOMRelayClient-dev.js +3.9% +4.4% 9.74 KB 10.12 KB 3.01 KB 3.15 KB FB_WWW_DEV
ReactFlightDOMRelayClient-prod.js 🔺+7.4% 🔺+5.8% 4.56 KB 4.89 KB 1.48 KB 1.56 KB FB_WWW_PROD

react-server

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-server.production.min.js 0.0% 🔺+0.2% 1.15 KB 1.15 KB 641 B 642 B NODE_PROD
react-server-flight.development.js +8.4% +4.0% 11.37 KB 12.33 KB 3.4 KB 3.54 KB NODE_DEV
react-server-flight.production.min.js 🔺+9.0% 🔺+2.1% 3.54 KB 3.85 KB 1.63 KB 1.66 KB NODE_PROD
react-server.development.js 0.0% +0.1% 5 KB 5 KB 1.56 KB 1.56 KB NODE_DEV
react-server-flight-server-runtime.production.min.js 0.0% 🔺+0.3% 493 B 493 B 330 B 331 B NODE_PROD

react-client

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-client-flight.development.js +7.4% +8.3% 12.26 KB 13.17 KB 3.71 KB 4.02 KB NODE_DEV
react-client-flight.production.min.js -0.8% 🔺+4.7% 3.12 KB 3.1 KB 1.38 KB 1.45 KB NODE_PROD

Size changes (stable)

Generated by 🚫 dangerJS against f332493

@sizebot
Copy link
Copy Markdown

sizebot commented Apr 3, 2020

Details of bundled changes.

Comparing: 59fd09c...f332493

react-flight-dom-webpack

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-flight-dom-webpack-server.browser.development.js +8.6% +4.1% 11.75 KB 12.75 KB 3.36 KB 3.5 KB UMD_DEV
react-flight-dom-webpack-server.browser.production.min.js 🔺+9.1% 🔺+2.2% 3.45 KB 3.77 KB 1.63 KB 1.67 KB UMD_PROD
react-flight-dom-webpack-server-runtime.development.js 0.0% +0.1% 2.56 KB 2.56 KB 934 B 935 B NODE_DEV
react-flight-dom-webpack-server-runtime.production.min.js 0.0% 🔺+0.3% 511 B 511 B 347 B 348 B NODE_PROD
react-flight-dom-webpack-server.node.development.js +8.1% +3.8% 11.8 KB 12.75 KB 3.53 KB 3.66 KB NODE_DEV
react-flight-dom-webpack-server.node.production.min.js 🔺+9.3% 🔺+2.1% 3.44 KB 3.76 KB 1.58 KB 1.61 KB NODE_PROD
react-flight-dom-webpack-server.browser.development.js +8.8% +4.1% 10.85 KB 11.81 KB 3.26 KB 3.39 KB NODE_DEV
react-flight-dom-webpack-plugin.development.js 0.0% -0.2% 682 B 682 B 405 B 404 B NODE_DEV
react-flight-dom-webpack-server.browser.production.min.js 🔺+9.8% 🔺+2.0% 3.26 KB 3.58 KB 1.55 KB 1.58 KB NODE_PROD
react-flight-dom-webpack-plugin.production.min.js 0.0% 🔺+0.3% 396 B 396 B 290 B 291 B NODE_PROD
react-flight-dom-webpack.development.js +6.3% +7.4% 15.37 KB 16.34 KB 4.32 KB 4.64 KB UMD_DEV
react-flight-dom-webpack.production.min.js -1.2% 🔺+2.5% 3.71 KB 3.67 KB 1.66 KB 1.7 KB UMD_PROD
react-flight-dom-webpack.development.js +6.5% +7.5% 14.28 KB 15.2 KB 4.21 KB 4.53 KB NODE_DEV
react-flight-dom-webpack.production.min.js -1.2% 🔺+3.3% 3.53 KB 3.49 KB 1.56 KB 1.61 KB NODE_PROD

react-flight-dom-relay

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactFlightDOMRelayServer-dev.js +8.8% +4.5% 11.02 KB 11.99 KB 3.2 KB 3.34 KB FB_WWW_DEV
ReactFlightDOMRelayClient-dev.js +3.9% +4.4% 9.74 KB 10.12 KB 3.01 KB 3.15 KB FB_WWW_DEV
ReactFlightDOMRelayClient-prod.js 🔺+7.4% 🔺+5.8% 4.56 KB 4.89 KB 1.48 KB 1.56 KB FB_WWW_PROD
ReactFlightDOMRelayServer-prod.js 🔺+9.2% 🔺+5.8% 7.6 KB 8.3 KB 2.22 KB 2.35 KB FB_WWW_PROD

react-server

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-server-flight.development.js +8.4% +4.0% 11.39 KB 12.34 KB 3.41 KB 3.55 KB NODE_DEV
react-server-flight.production.min.js 🔺+9.0% 🔺+2.1% 3.55 KB 3.87 KB 1.63 KB 1.67 KB NODE_PROD
react-server.development.js 0.0% +0.1% 5.01 KB 5.01 KB 1.57 KB 1.57 KB NODE_DEV
react-server.production.min.js 0.0% 🔺+0.2% 1.16 KB 1.16 KB 649 B 650 B NODE_PROD
react-server-flight-server-runtime.development.js 0.0% +0.1% 2.55 KB 2.55 KB 925 B 926 B NODE_DEV

react-client

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-client-flight.development.js +7.4% +8.2% 12.27 KB 13.18 KB 3.72 KB 4.03 KB NODE_DEV
react-client-flight.production.min.js -0.8% 🔺+4.6% 3.13 KB 3.11 KB 1.39 KB 1.46 KB NODE_PROD

Size changes (experimental)

Generated by 🚫 dangerJS against f332493

Comment thread packages/react-client/src/ReactFlightClient.js Outdated
This ensures that we don't spend CPU cycles processing models that we're
not going to end up rendering.

This model will also allow us to suspend during this initialization if
data is not yet available to satisfy the model.
The root model needs to be cast at one point or another same as othe
chunks. So we can parameterize the read instead of the whole Response.
The special case to read the root isn't worth the field and code.
Instead of storing it on the data tuple which is kind of dynamic, we store
it on each Chunk. This uses more memory. Especially compared to just making
initializeBlock a closure, but overall is simpler.
Response objects are exposed.
This allows us to stream in server components one after another over the
wire. It also allows parallelizing their fetches and resuming only the
server component instead of the whole parent block.

This doesn't yet allow us to suspend deeper while waiting on this content
because we don't have "lazy elements".
@sebmarkbage sebmarkbage merged commit e2dd308 into facebook:master Apr 3, 2020
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.

5 participants