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

[Fizz] Implement Legacy renderToString and renderToNodeStream on top of Fizz #21276

Merged
merged 11 commits into from
Jun 14, 2021

Conversation

sebmarkbage
Copy link
Collaborator

@sebmarkbage sebmarkbage commented Apr 15, 2021

I use a separate build from the main Fizz build because it uses a slightly different configuration. This adds a custom StreamConfig that only uses strings and pushes to a readable-like API.

I enabled the new builds in experimental/modern.

This variant of Fizz uses an infinite progressiveChunkSize and it always waits until everything is completed until starting to write. The effect of this is that the output should never include any scripts and always just render HTML.

Suspending works in both but renderToString switches to client rendering for those cases. renderToNodeStream waits to start writing anything to the stream until they all resolve.

renderToNodeStream will have very different performance characteristics because this new variant will eagerly build up as much HTML as possible as aggressively as possible. This is the new strategy we're going after. If that's not good, then adding more suspense breaks it up. This API should be deprecated and switching to the Fizz model is preferred. While the previous approach of renderToNodeStream is somewhat valid, it's not inline with the future strategy so I don't plan on having a true replacement for CPU throttled. Instead, we could use some level of time slicing at suspense boundary levels in the full Fizz.

This now uses a wrapper around the FormatConfig. This allows us to do custom overrides of the HTML for legacy purposes. This also supports static markup generation (not hydratable HTML). Static mark up isn't legacy per se but the newer version might use something like an optimization of Server Components rather than its own mode. For now, renderToStaticMarkup and renderToStaticNodeStream mode is supported.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Apr 15, 2021
@sizebot
Copy link

sizebot commented Apr 15, 2021

Comparing: 1a106bd...c24b569

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 = 126.89 kB 126.89 kB = 40.69 kB 40.69 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js = 129.70 kB 129.70 kB = 41.61 kB 41.61 kB
facebook-www/ReactDOM-prod.classic.js = 406.00 kB 406.00 kB = 75.07 kB 75.07 kB
facebook-www/ReactDOM-prod.modern.js = 394.35 kB 394.35 kB = 73.25 kB 73.25 kB
facebook-www/ReactDOMForked-prod.classic.js = 406.00 kB 406.00 kB = 75.07 kB 75.07 kB
oss-stable-semver/react-dom/cjs/react-dom-server.node.production.min.js +56.20% 20.91 kB 32.66 kB +39.24% 7.76 kB 10.81 kB
oss-stable/react-dom/cjs/react-dom-server.node.production.min.js +56.20% 20.91 kB 32.66 kB +39.24% 7.76 kB 10.81 kB
oss-experimental/react-dom/cjs/react-dom-server.node.production.min.js +56.02% 21.02 kB 32.80 kB +39.19% 7.81 kB 10.86 kB
oss-experimental/react-dom/cjs/react-dom-server.browser.production.min.js +55.95% 20.59 kB 32.11 kB +38.86% 7.64 kB 10.61 kB
oss-experimental/react-dom/umd/react-dom-server.browser.production.min.js +55.45% 20.77 kB 32.29 kB +39.22% 7.72 kB 10.75 kB
oss-experimental/react-dom/cjs/react-dom-server.browser.development.js +51.92% 143.56 kB 218.09 kB +37.75% 37.75 kB 52.00 kB
oss-experimental/react-dom/cjs/react-dom-server.node.development.js +51.65% 144.86 kB 219.67 kB +37.94% 38.01 kB 52.43 kB
oss-stable-semver/react-dom/cjs/react-dom-server.node.development.js +51.58% 144.54 kB 219.09 kB +37.77% 37.93 kB 52.26 kB
oss-stable/react-dom/cjs/react-dom-server.node.development.js +51.58% 144.54 kB 219.09 kB +37.77% 37.93 kB 52.26 kB
oss-experimental/react-dom/umd/react-dom-server.browser.development.js +51.57% 151.23 kB 229.22 kB +37.56% 38.22 kB 52.58 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-server.production.min.js +5.24% 2.67 kB 2.81 kB +1.42% 1.06 kB 1.07 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-server.production.min.js +5.24% 2.67 kB 2.81 kB +1.42% 1.06 kB 1.07 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-server.production.min.js +5.24% 2.67 kB 2.81 kB +1.42% 1.06 kB 1.07 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-server.development.js +4.49% 5.54 kB 5.79 kB +0.94% 1.59 kB 1.61 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-server.development.js +4.49% 5.54 kB 5.79 kB +0.94% 1.59 kB 1.61 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-server.development.js +4.49% 5.54 kB 5.79 kB +0.94% 1.59 kB 1.61 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-dom/cjs/react-dom-server.node.production.min.js +56.20% 20.91 kB 32.66 kB +39.24% 7.76 kB 10.81 kB
oss-stable/react-dom/cjs/react-dom-server.node.production.min.js +56.20% 20.91 kB 32.66 kB +39.24% 7.76 kB 10.81 kB
oss-experimental/react-dom/cjs/react-dom-server.node.production.min.js +56.02% 21.02 kB 32.80 kB +39.19% 7.81 kB 10.86 kB
oss-experimental/react-dom/cjs/react-dom-server.browser.production.min.js +55.95% 20.59 kB 32.11 kB +38.86% 7.64 kB 10.61 kB
oss-experimental/react-dom/umd/react-dom-server.browser.production.min.js +55.45% 20.77 kB 32.29 kB +39.22% 7.72 kB 10.75 kB
oss-experimental/react-dom/cjs/react-dom-server.browser.development.js +51.92% 143.56 kB 218.09 kB +37.75% 37.75 kB 52.00 kB
oss-experimental/react-dom/cjs/react-dom-server.node.development.js +51.65% 144.86 kB 219.67 kB +37.94% 38.01 kB 52.43 kB
oss-stable-semver/react-dom/cjs/react-dom-server.node.development.js +51.58% 144.54 kB 219.09 kB +37.77% 37.93 kB 52.26 kB
oss-stable/react-dom/cjs/react-dom-server.node.development.js +51.58% 144.54 kB 219.09 kB +37.77% 37.93 kB 52.26 kB
oss-experimental/react-dom/umd/react-dom-server.browser.development.js +51.57% 151.23 kB 229.22 kB +37.56% 38.22 kB 52.58 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-server.production.min.js +5.24% 2.67 kB 2.81 kB +1.42% 1.06 kB 1.07 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-server.production.min.js +5.24% 2.67 kB 2.81 kB +1.42% 1.06 kB 1.07 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-server.production.min.js +5.24% 2.67 kB 2.81 kB +1.42% 1.06 kB 1.07 kB
oss-experimental/react-noop-renderer/cjs/react-noop-renderer-server.development.js +4.49% 5.54 kB 5.79 kB +0.94% 1.59 kB 1.61 kB
oss-stable-semver/react-noop-renderer/cjs/react-noop-renderer-server.development.js +4.49% 5.54 kB 5.79 kB +0.94% 1.59 kB 1.61 kB
oss-stable/react-noop-renderer/cjs/react-noop-renderer-server.development.js +4.49% 5.54 kB 5.79 kB +0.94% 1.59 kB 1.61 kB
oss-stable-semver/react-server/cjs/react-server.production.min.js +1.55% 17.25 kB 17.52 kB +0.47% 5.92 kB 5.95 kB
oss-stable/react-server/cjs/react-server.production.min.js +1.55% 17.25 kB 17.52 kB +0.47% 5.92 kB 5.95 kB
oss-experimental/react-server/cjs/react-server.production.min.js +1.54% 17.37 kB 17.64 kB +0.47% 5.96 kB 5.99 kB
oss-stable-semver/react-server/cjs/react-server.development.js +0.36% 116.09 kB 116.51 kB +0.10% 28.62 kB 28.65 kB
oss-stable/react-server/cjs/react-server.development.js +0.36% 116.09 kB 116.51 kB +0.10% 28.62 kB 28.65 kB
oss-experimental/react-server/cjs/react-server.development.js +0.36% 116.65 kB 117.07 kB +0.10% 28.79 kB 28.82 kB
facebook-www/ReactDOMServer-dev.modern.js +0.30% 216.56 kB 217.21 kB +0.07% 50.90 kB 50.93 kB
oss-stable-semver/react-dom/cjs/react-dom-unstable-fizz.node.development.js +0.24% 214.03 kB 214.54 kB +0.05% 51.24 kB 51.26 kB
oss-stable/react-dom/cjs/react-dom-unstable-fizz.node.development.js +0.24% 214.03 kB 214.54 kB +0.05% 51.24 kB 51.26 kB
oss-stable-semver/react-dom/cjs/react-dom-unstable-fizz.browser.development.js +0.24% 214.25 kB 214.76 kB +0.05% 51.41 kB 51.43 kB
oss-stable/react-dom/cjs/react-dom-unstable-fizz.browser.development.js +0.24% 214.25 kB 214.76 kB +0.05% 51.41 kB 51.43 kB
oss-experimental/react-dom/cjs/react-dom-unstable-fizz.node.development.js +0.24% 214.59 kB 215.10 kB +0.05% 51.40 kB 51.43 kB
oss-experimental/react-dom/cjs/react-dom-unstable-fizz.browser.development.js +0.24% 214.81 kB 215.32 kB +0.05% 51.57 kB 51.59 kB
oss-stable-semver/react-dom/umd/react-dom-unstable-fizz.browser.development.js +0.23% 225.16 kB 225.68 kB +0.05% 51.99 kB 52.01 kB
oss-stable/react-dom/umd/react-dom-unstable-fizz.browser.development.js +0.23% 225.16 kB 225.68 kB +0.05% 51.99 kB 52.01 kB
oss-experimental/react-dom/umd/react-dom-unstable-fizz.browser.development.js +0.23% 225.76 kB 226.29 kB +0.05% 52.14 kB 52.16 kB
oss-experimental/react-dom/umd/react-dom-unstable-fizz.browser.production.min.js = 32.48 kB 32.41 kB +0.08% 10.99 kB 11.00 kB
oss-stable-semver/react-dom/umd/react-dom-unstable-fizz.browser.production.min.js = 32.36 kB 32.29 kB = 10.95 kB 10.95 kB
oss-stable/react-dom/umd/react-dom-unstable-fizz.browser.production.min.js = 32.36 kB 32.29 kB = 10.95 kB 10.95 kB
oss-experimental/react-dom/cjs/react-dom-unstable-fizz.browser.production.min.js = 32.31 kB 32.24 kB = 10.88 kB 10.87 kB
oss-stable-semver/react-dom/cjs/react-dom-unstable-fizz.browser.production.min.js = 32.19 kB 32.12 kB = 10.84 kB 10.83 kB
oss-stable/react-dom/cjs/react-dom-unstable-fizz.browser.production.min.js = 32.19 kB 32.12 kB = 10.84 kB 10.83 kB

Generated by 🚫 dangerJS against c24b569

@curtcurt871

This comment has been minimized.

@curtcurt871

This comment has been minimized.

@sebmarkbage
Copy link
Collaborator Author

sebmarkbage commented Apr 26, 2021

The way this set up works, the stable tests doesn't actually run against stable because jest doesn't use the entry point override thing. That's only set up for builds. Tests against builds run against stable though. But basically because of this, I can't use the test gating feature.

The other issue is that I want to expose both this legacy build and unstable-fizz on a single module entry point with different export names. Because when migrating you shouldn't need to migrate to a new name and then back later. But the way tests fork the host config, is based on the entry point so that whole thing doesn't work.

So we'll need to put some significant build/test infra work in to land this.

I think this might be faster. We could probably use a combination of this
technique in the stream too to lower the overhead.
Maybe this should always error but in the async forms we can just delay
the stream until it resolves so it does have some useful semantics.

In the synchronous form it's never useful though. I'm mostly adding the
error because we're testing this behavior for renderToString specifically.
@sebmarkbage sebmarkbage changed the title [WIP] [Fizz] Implement Legacy renderToString and renderToNodeStream on top of Fizz [Fizz] Implement Legacy renderToString and renderToNodeStream on top of Fizz Jun 14, 2021
@sebmarkbage sebmarkbage force-pushed the fizzlegacy branch 2 times, most recently from c01c3fb to 199943e Compare June 14, 2021 19:01
These tests don't translate as is to the new implementation and have been
ported to the Fizz tests separately.
This ensures that we can inject custom overrides without negatively
affecting the new implementation.

This adds another field for static mark up for example.
Completed and client rendered boundaries are only marked for the client
to take over.

Pending boundaries are still supported in case you stream non-hydratable
mark up.
@sebmarkbage sebmarkbage force-pushed the fizzlegacy branch 2 times, most recently from 672dd7f to 1b72b75 Compare June 14, 2021 19:43
This shouldn't affect the FB one ideally but it's done with the same build
so let's hope this works.
@sebmarkbage sebmarkbage merged commit dbe3363 into facebook:master Jun 14, 2021
koto pushed a commit to koto/react that referenced this pull request Jun 15, 2021
…of Fizz (facebook#21276)

* Wire up DOM legacy build

* Hack to filter extra comments for testing purposes

* Use string concat in renderToString

I think this might be faster. We could probably use a combination of this
technique in the stream too to lower the overhead.

* Error if we can't complete the root synchronously

Maybe this should always error but in the async forms we can just delay
the stream until it resolves so it does have some useful semantics.

In the synchronous form it's never useful though. I'm mostly adding the
error because we're testing this behavior for renderToString specifically.

* Gate memory leak tests of internals

These tests don't translate as is to the new implementation and have been
ported to the Fizz tests separately.

* Enable Fizz legacy mode in stable

* Add wrapper around the ServerFormatConfig for legacy mode

This ensures that we can inject custom overrides without negatively
affecting the new implementation.

This adds another field for static mark up for example.

* Wrap pushTextInstance to avoid emitting comments for text in static markup

* Don't emit static mark up for completed suspense boundaries

Completed and client rendered boundaries are only marked for the client
to take over.

Pending boundaries are still supported in case you stream non-hydratable
mark up.

* Wire up generateStaticMarkup to static API entry points

* Mark as renderer for stable

This shouldn't affect the FB one ideally but it's done with the same build
so let's hope this works.
facebook-github-bot pushed a commit to facebook/react-native that referenced this pull request Jun 22, 2021
Summary:
This sync includes the following changes:
- **[43f4cc160](facebook/react@43f4cc160 )**: Fix failing test ([#21697](facebook/react#21697)) //<Dan Abramov>//
- **[d0f348dc1](facebook/react@d0f348dc1 )**: Fix for failed Suspense layout semantics ([#21694](facebook/react#21694)) //<Brian Vaughn>//
- **[bd0a96344](facebook/react@bd0a96344 )**: Throw when `act` is used in production ([#21686](facebook/react#21686)) //<Andrew Clark>//
- **[9343f8720](facebook/react@9343f8720 )**: Use the server src files as entry points for the builds/tests ([#21683](facebook/react#21683)) //<Sebastian Markbåge>//
- **[502f8a2a0](facebook/react@502f8a2a0 )**: [Fizz/Flight] Don't use default args ([#21681](facebook/react#21681)) //<Sebastian Markbåge>//
- **[a8f5e77b9](facebook/react@a8f5e77b9 )**: Remove invokeGuardedCallback from commit phase ([#21666](facebook/react#21666)) //<Dan Abramov>//
- **[dbe3363cc](facebook/react@dbe3363cc )**: [Fizz] Implement Legacy renderToString and renderToNodeStream on top of Fizz ([#21276](facebook/react#21276)) //<Sebastian Markbåge>//
- **[101ea9f55](facebook/react@101ea9f55 )**: Set deletedTreeCleanUpLevel to 3 ([#21679](facebook/react#21679)) //<Dan Abramov>//
- **[1a106bdc2](facebook/react@1a106bdc2 )**: Wrap eventhandle-specific logic in a flag ([#21657](facebook/react#21657)) //<Dan Abramov>//
- **[cb30388d1](facebook/react@cb30388d1 )**: Export React Native `AttributeType` Types ([#21661](facebook/react#21661)) //<Timothy Yung>//
- **[c1536795c](facebook/react@c1536795c )**: Revert "Make enableSuspenseLayoutEffectSemantics static for www ([#21617](facebook/react#21617))" ([#21656](facebook/react#21656)) //<Sebastian Markbåge>//

Changelog:
[General][Changed] - React Native sync for revisions c96b78e...568dc35

jest_e2e[run_all_tests]

Reviewed By: rickhanlonii

Differential Revision: D29303157

fbshipit-source-id: 90952885eb2264f4effa04070357b80700bb9be3
@wood1986
Copy link

Hey @sebmarkbage, I have questions about Readable in ReactMarkupReadableStream. Instead of using Readable, is ReactMarkupReadableStream possible to extends from web stream ReadableStream in the future?

Currently, I am trying to use cloudflare worker to do the SSR rendering. I have my own webpack plugin to build the js for cloudflare worker to run. My own plugin currently needs to specify the fallback for two dependencies stream and util with stream-browserify and util. They will be included in SSR js and I do not want that.

If ReactMarkupReadableStream extends ReadableStream, then I do not need to specify the fallback. stream-browserify and util will not be included in my SSR js for cloudflare to run.

@gaearon gaearon mentioned this pull request Mar 29, 2022
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