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

[Fiber] Support Suspense boundaries anywhere (excluding hydration) #32163

Merged
merged 1 commit into from
Jan 29, 2025

Conversation

gnoff
Copy link
Collaborator

@gnoff gnoff commented Jan 22, 2025

This is a follow up to #32069

In the prior change I updated Fizz to allow you to render Suspense boundaries at any level within a react-dom application by treating the document body as the default render scope. This change updates Fiber to provide similar semantics. Note that this update still does not deliver hydration so unifying the Fizz and Fiber implementations in a single App is not possible yet.

The implementation required a rework of the getHostSibling and getHostParent algorithms. Now most HostSingletons are invisible from a host positioning perspective. Head is special in that it is a valid host scope so when you have Placements inside of it, it will act as the parent. But body, and html, will not directly participate in host positioning.

Additionally to support flipping to a fallback html, head, and body tag in a Suspense fallback I updated the offscreen hiding/unhide logic to pierce through singletons when lookin for matching hidable nod boundaries anywhere (excluding hydration)

@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Jan 22, 2025
@gnoff gnoff force-pushed the suspense-anywhere-fiber-render branch 2 times, most recently from ea3ae19 to 3089cbf Compare January 22, 2025 22:42
@@ -130,6 +131,8 @@ export const PassiveTransitionMask: number = PassiveMask | Update | Placement;
// This allows certain concepts to persist without recalculating them,
// e.g. whether a subtree contains passive effects or portals.
export const StaticMask =
SnapshotStatic |
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 this was missed so I added it

@react-sizebot
Copy link

react-sizebot commented Jan 22, 2025

Comparing: 37906d4...38a8997

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 +0.17% 514.24 kB 515.10 kB +0.08% 91.74 kB 91.81 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 +0.07% 557.28 kB 557.69 kB = 98.97 kB 98.87 kB
facebook-www/ReactDOM-prod.classic.js +0.22% 595.79 kB 597.07 kB +0.09% 104.85 kB 104.95 kB
facebook-www/ReactDOM-prod.modern.js +0.22% 586.21 kB 587.50 kB +0.10% 103.30 kB 103.41 kB
facebook-www/ReactFreshRuntime-dev.classic.js = 13.82 kB 12.37 kB = 3.19 kB 2.99 kB
facebook-www/ReactFreshRuntime-dev.modern.js = 13.82 kB 12.37 kB = 3.19 kB 2.99 kB
oss-experimental/react-refresh/cjs/react-refresh-runtime.development.js = 13.80 kB 12.36 kB = 3.18 kB 2.98 kB
oss-stable-semver/react-refresh/cjs/react-refresh-runtime.development.js = 13.80 kB 12.36 kB = 3.18 kB 2.98 kB
oss-stable/react-refresh/cjs/react-refresh-runtime.development.js = 13.80 kB 12.36 kB = 3.18 kB 2.98 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
facebook-www/ReactReconciler-prod.modern.js +0.24% 451.22 kB 452.32 kB +0.12% 72.55 kB 72.63 kB
facebook-www/ReactReconciler-prod.classic.js +0.24% 461.37 kB 462.46 kB +0.12% 74.11 kB 74.19 kB
facebook-www/ReactDOM-prod.modern.js +0.22% 586.21 kB 587.50 kB +0.10% 103.30 kB 103.41 kB
facebook-www/ReactDOM-prod.classic.js +0.22% 595.79 kB 597.07 kB +0.09% 104.85 kB 104.95 kB
facebook-www/ReactDOMTesting-prod.modern.js +0.21% 600.93 kB 602.22 kB +0.09% 107.00 kB 107.10 kB
facebook-react-native/react-dom/cjs/ReactDOMClient-prod.js +0.21% 539.50 kB 540.65 kB +0.13% 95.75 kB 95.87 kB
facebook-www/ReactDOM-profiling.modern.js +0.21% 613.21 kB 614.51 kB +0.11% 107.13 kB 107.25 kB
facebook-www/ReactDOMTesting-prod.classic.js +0.21% 610.50 kB 611.79 kB +0.09% 108.54 kB 108.64 kB
oss-stable-semver/react-reconciler/cjs/react-reconciler.production.js +0.21% 389.90 kB 390.72 kB +0.15% 63.27 kB 63.37 kB
oss-stable/react-reconciler/cjs/react-reconciler.production.js +0.21% 389.92 kB 390.74 kB +0.15% 63.30 kB 63.39 kB
facebook-react-native/react-dom/cjs/ReactDOMProfiling-prod.js +0.21% 545.01 kB 546.16 kB +0.13% 96.82 kB 96.95 kB
facebook-www/ReactDOM-profiling.classic.js +0.21% 622.83 kB 624.13 kB +0.11% 108.71 kB 108.83 kB
facebook-react-native/react-dom/cjs/ReactDOMClient-profiling.js +0.21% 564.32 kB 565.49 kB +0.09% 99.51 kB 99.60 kB
facebook-react-native/react-dom/cjs/ReactDOMProfiling-profiling.js +0.20% 570.27 kB 571.43 kB +0.09% 100.67 kB 100.76 kB
oss-experimental/react-art/cjs/react-art.production.js = 322.55 kB 321.50 kB = 54.86 kB 54.63 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.production.js = 94.25 kB 93.93 kB = 19.49 kB 19.44 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.production.js = 92.33 kB 92.01 kB = 19.07 kB 19.02 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.production.js = 90.80 kB 90.48 kB = 18.74 kB 18.69 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.production.js = 89.79 kB 89.47 kB = 18.75 kB 18.70 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.production.js = 89.79 kB 89.47 kB = 18.75 kB 18.70 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.production.js = 87.73 kB 87.42 kB = 18.33 kB 18.29 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.production.js = 87.73 kB 87.42 kB = 18.33 kB 18.29 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.production.js = 86.29 kB 85.98 kB = 18.01 kB 17.96 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.production.js = 86.29 kB 85.98 kB = 18.01 kB 17.96 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js = 149.08 kB 148.52 kB = 27.72 kB 27.62 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js = 148.81 kB 148.25 kB = 27.49 kB 27.39 kB
oss-experimental/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js = 144.35 kB 143.78 kB = 26.76 kB 26.66 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js = 135.37 kB 134.81 kB = 25.33 kB 25.22 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.node.development.js = 135.37 kB 134.81 kB = 25.33 kB 25.22 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js = 134.15 kB 133.59 kB = 25.02 kB 24.91 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.edge.development.js = 134.15 kB 133.59 kB = 25.02 kB 24.91 kB
oss-stable-semver/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js = 131.38 kB 130.82 kB = 24.49 kB 24.40 kB
oss-stable/react-server-dom-parcel/cjs/react-server-dom-parcel-server.browser.development.js = 131.38 kB 130.82 kB = 24.49 kB 24.40 kB
oss-experimental/react/cjs/react.development.js = 46.15 kB 45.83 kB = 10.53 kB 10.47 kB
oss-experimental/react/cjs/react.production.js = 18.42 kB 18.13 kB = 4.77 kB 4.71 kB
oss-experimental/react-debug-tools/cjs/react-debug-tools.development.js = 32.24 kB 31.60 kB = 5.77 kB 5.69 kB
oss-stable-semver/react-debug-tools/cjs/react-debug-tools.development.js = 32.24 kB 31.60 kB = 5.77 kB 5.69 kB
oss-stable/react-debug-tools/cjs/react-debug-tools.development.js = 32.24 kB 31.60 kB = 5.77 kB 5.69 kB
oss-experimental/react-debug-tools/cjs/react-debug-tools.production.js = 28.72 kB 28.15 kB = 5.64 kB 5.56 kB
oss-stable-semver/react-debug-tools/cjs/react-debug-tools.production.js = 28.72 kB 28.15 kB = 5.64 kB 5.56 kB
oss-stable/react-debug-tools/cjs/react-debug-tools.production.js = 28.72 kB 28.15 kB = 5.64 kB 5.56 kB
facebook-www/ReactFreshRuntime-dev.classic.js = 13.82 kB 12.37 kB = 3.19 kB 2.99 kB
facebook-www/ReactFreshRuntime-dev.modern.js = 13.82 kB 12.37 kB = 3.19 kB 2.99 kB
oss-experimental/react-refresh/cjs/react-refresh-runtime.development.js = 13.80 kB 12.36 kB = 3.18 kB 2.98 kB
oss-stable-semver/react-refresh/cjs/react-refresh-runtime.development.js = 13.80 kB 12.36 kB = 3.18 kB 2.98 kB
oss-stable/react-refresh/cjs/react-refresh-runtime.development.js = 13.80 kB 12.36 kB = 3.18 kB 2.98 kB

Generated by 🚫 dangerJS against 6e675b4

@gnoff gnoff requested a review from sebmarkbage January 22, 2025 23:03
Copy link
Contributor

@acdlite acdlite left a comment

Choose a reason for hiding this comment

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

The flag-related changes look good to me

@gnoff gnoff force-pushed the suspense-anywhere-fiber-render branch 2 times, most recently from c5a9a78 to 6cd02da Compare January 24, 2025 16:53
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 25, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 26, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 26, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 27, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 27, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Jan 28, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
This is a follow up to facebook#32069

In the prior change I updated Fizz to allow you to render Suspense boundaries at any level within a react-dom application by treating the document body as the default render scope. This change updates Fiber to provide similar semantics. Note that this update still does not deliver hydration so unifying the Fizz and Fiber implementations in a single App is not possible yet.

The implementation required a rework of the getHostSibling and getHostParent algorithms. Now most HostSingletons are invisible from a host positioning perspective. Head is special in that it is a valid host scope so when you have Placements inside of it, it will act as the parent. But body, and html, will not directly participate in host positioning.

Additionally to support flipping to a fallback <html>, <head>, and <body> tag in a Suspense fallback I updated the offscreen hiding/unhide logic to pierce through singletons when lookin for matching hidable nod boundaries anywhere (excluding hydration)
@gnoff gnoff force-pushed the suspense-anywhere-fiber-render branch from 6cd02da to 6e675b4 Compare January 28, 2025 03:53
gnoff added a commit to gnoff/react that referenced this pull request Jan 28, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
@gnoff gnoff merged commit c492f97 into facebook:main Jan 29, 2025
188 checks passed
@gnoff gnoff deleted the suspense-anywhere-fiber-render branch January 29, 2025 06:42
gnoff added a commit to gnoff/react that referenced this pull request Jan 29, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
github-actions bot pushed a commit that referenced this pull request Jan 29, 2025
…32163)

This is a follow up to #32069

In the prior change I updated Fizz to allow you to render Suspense
boundaries at any level within a react-dom application by treating the
document body as the default render scope. This change updates Fiber to
provide similar semantics. Note that this update still does not deliver
hydration so unifying the Fizz and Fiber implementations in a single App
is not possible yet.

The implementation required a rework of the getHostSibling and
getHostParent algorithms. Now most HostSingletons are invisible from a
host positioning perspective. Head is special in that it is a valid host
scope so when you have Placements inside of it, it will act as the
parent. But body, and html, will not directly participate in host
positioning.

Additionally to support flipping to a fallback html, head, and body tag
in a Suspense fallback I updated the offscreen hiding/unhide logic to
pierce through singletons when lookin for matching hidable nod
boundaries anywhere (excluding hydration)

DiffTrain build for [c492f97](c492f97)
github-actions bot pushed a commit that referenced this pull request Jan 29, 2025
…32163)

This is a follow up to #32069

In the prior change I updated Fizz to allow you to render Suspense
boundaries at any level within a react-dom application by treating the
document body as the default render scope. This change updates Fiber to
provide similar semantics. Note that this update still does not deliver
hydration so unifying the Fizz and Fiber implementations in a single App
is not possible yet.

The implementation required a rework of the getHostSibling and
getHostParent algorithms. Now most HostSingletons are invisible from a
host positioning perspective. Head is special in that it is a valid host
scope so when you have Placements inside of it, it will act as the
parent. But body, and html, will not directly participate in host
positioning.

Additionally to support flipping to a fallback html, head, and body tag
in a Suspense fallback I updated the offscreen hiding/unhide logic to
pierce through singletons when lookin for matching hidable nod
boundaries anywhere (excluding hydration)

DiffTrain build for [c492f97](c492f97)
github-actions bot pushed a commit to code/lib-react that referenced this pull request Jan 29, 2025
…acebook#32163)

This is a follow up to facebook#32069

In the prior change I updated Fizz to allow you to render Suspense
boundaries at any level within a react-dom application by treating the
document body as the default render scope. This change updates Fiber to
provide similar semantics. Note that this update still does not deliver
hydration so unifying the Fizz and Fiber implementations in a single App
is not possible yet.

The implementation required a rework of the getHostSibling and
getHostParent algorithms. Now most HostSingletons are invisible from a
host positioning perspective. Head is special in that it is a valid host
scope so when you have Placements inside of it, it will act as the
parent. But body, and html, will not directly participate in host
positioning.

Additionally to support flipping to a fallback html, head, and body tag
in a Suspense fallback I updated the offscreen hiding/unhide logic to
pierce through singletons when lookin for matching hidable nod
boundaries anywhere (excluding hydration)

DiffTrain build for [c492f97](facebook@c492f97)
github-actions bot pushed a commit to code/lib-react that referenced this pull request Jan 29, 2025
…acebook#32163)

This is a follow up to facebook#32069

In the prior change I updated Fizz to allow you to render Suspense
boundaries at any level within a react-dom application by treating the
document body as the default render scope. This change updates Fiber to
provide similar semantics. Note that this update still does not deliver
hydration so unifying the Fizz and Fiber implementations in a single App
is not possible yet.

The implementation required a rework of the getHostSibling and
getHostParent algorithms. Now most HostSingletons are invisible from a
host positioning perspective. Head is special in that it is a valid host
scope so when you have Placements inside of it, it will act as the
parent. But body, and html, will not directly participate in host
positioning.

Additionally to support flipping to a fallback html, head, and body tag
in a Suspense fallback I updated the offscreen hiding/unhide logic to
pierce through singletons when lookin for matching hidable nod
boundaries anywhere (excluding hydration)

DiffTrain build for [c492f97](facebook@c492f97)
gnoff added a commit to gnoff/react that referenced this pull request Feb 1, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Feb 1, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Feb 1, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Feb 1, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Feb 1, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit to gnoff/react that referenced this pull request Feb 1, 2025
stacked on facebook#32163

This continues the work of making Suspense workable anywhere in a react-dom tree. See the prior PRs for how we handle server rendering and client rendering. In this change we update the hydration implementation to be able to locate expected nodes. In particular this means hydration understands now that the default hydration context is the document body when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries. When hydration fails or when the server instructs the client to recover an errored boundary it's possible that the html, head, and body tags in the initial document were written from a fallback or a different primary content on the server and need to be replaced by the client render. However these tags (and in the case of head, their content) won't be inside the comment nodes that identify the bounds of the Suspense boundary. And when client rendering you may not even render the same singletons that were server rendered. So when server rendering a boudnary which contributes to the preamble (the html, head, and body tag openings plus the head contents) we emit a special marker comment just before closing the boundary out. This marker encodes which parts of the preamble this boundary owned. If we need to clear the suspense boundary on the client we read this marker and use it to reset the appropriate singleton state.
gnoff added a commit that referenced this pull request Feb 4, 2025
follow up to #32163

This continues the work of making Suspense workable anywhere in a
react-dom tree. See the prior PRs for how we handle server rendering and
client rendering. In this change we update the hydration implementation
to be able to locate expected nodes. In particular this means hydration
understands now that the default hydration context is the document body
when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries.
When hydration fails or when the server instructs the client to recover
an errored boundary it's possible that the html, head, and body tags in
the initial document were written from a fallback or a different primary
content on the server and need to be replaced by the client render.
However these tags (and in the case of head, their content) won't be
inside the comment nodes that identify the bounds of the Suspense
boundary. And when client rendering you may not even render the same
singletons that were server rendered. So when server rendering a
boudnary which contributes to the preamble (the html, head, and body tag
openings plus the head contents) we emit a special marker comment just
before closing the boundary out. This marker encodes which parts of the
preamble this boundary owned. If we need to clear the suspense boundary
on the client we read this marker and use it to reset the appropriate
singleton state.
github-actions bot pushed a commit that referenced this pull request Feb 4, 2025
follow up to #32163

This continues the work of making Suspense workable anywhere in a
react-dom tree. See the prior PRs for how we handle server rendering and
client rendering. In this change we update the hydration implementation
to be able to locate expected nodes. In particular this means hydration
understands now that the default hydration context is the document body
when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries.
When hydration fails or when the server instructs the client to recover
an errored boundary it's possible that the html, head, and body tags in
the initial document were written from a fallback or a different primary
content on the server and need to be replaced by the client render.
However these tags (and in the case of head, their content) won't be
inside the comment nodes that identify the bounds of the Suspense
boundary. And when client rendering you may not even render the same
singletons that were server rendered. So when server rendering a
boudnary which contributes to the preamble (the html, head, and body tag
openings plus the head contents) we emit a special marker comment just
before closing the boundary out. This marker encodes which parts of the
preamble this boundary owned. If we need to clear the suspense boundary
on the client we read this marker and use it to reset the appropriate
singleton state.

DiffTrain build for [8bda715](8bda715)
github-actions bot pushed a commit that referenced this pull request Feb 4, 2025
follow up to #32163

This continues the work of making Suspense workable anywhere in a
react-dom tree. See the prior PRs for how we handle server rendering and
client rendering. In this change we update the hydration implementation
to be able to locate expected nodes. In particular this means hydration
understands now that the default hydration context is the document body
when the container is above the body.

One case that is unique to hydration is clearing Suspense boundaries.
When hydration fails or when the server instructs the client to recover
an errored boundary it's possible that the html, head, and body tags in
the initial document were written from a fallback or a different primary
content on the server and need to be replaced by the client render.
However these tags (and in the case of head, their content) won't be
inside the comment nodes that identify the bounds of the Suspense
boundary. And when client rendering you may not even render the same
singletons that were server rendered. So when server rendering a
boudnary which contributes to the preamble (the html, head, and body tag
openings plus the head contents) we emit a special marker comment just
before closing the boundary out. This marker encodes which parts of the
preamble this boundary owned. If we need to clear the suspense boundary
on the client we read this marker and use it to reset the appropriate
singleton state.

DiffTrain build for [8bda715](8bda715)
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