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

Support implicit <head> in hydration #24973

Closed
wants to merge 1 commit into from

Conversation

gnoff
Copy link
Collaborator

@gnoff gnoff commented Jul 21, 2022

When the browser parses html it will create a element even if the tag is not present. If you render at the root (either the document itself or the html element) the hydration will fail becasue this implicitly created head is not matched against the react component tree. Additionally the head will be removed from the document as an extraneous node which means any third party scripts or other tags that were inserted there by browser extensions or other means will be deleted which can break many tools.

This change adds the ability to mark certain instances as implicit and so after attempting to hydrate them they will be skipped over rather than dropped.

@sophiebits
Copy link
Collaborator

Would it be better to warn when rendering <html> without a <head> child? eg for <table>, we require a <tbody> component to be explicitly rendered, rather than attempting to recover automatically. That way we don't need production code to handle it.

@sizebot
Copy link

sizebot commented Jul 21, 2022

Comparing: 3ddbedd...98bb822

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 +0.07% 132.92 kB 133.02 kB +0.06% 42.68 kB 42.71 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.07% 138.15 kB 138.24 kB +0.05% 44.19 kB 44.21 kB
facebook-www/ReactDOM-prod.classic.js +0.05% 469.02 kB 469.26 kB +0.04% 84.22 kB 84.26 kB
facebook-www/ReactDOM-prod.modern.js +0.05% 454.26 kB 454.50 kB +0.06% 81.98 kB 82.03 kB
facebook-www/ReactDOMForked-prod.classic.js +0.05% 469.02 kB 469.26 kB +0.04% 84.22 kB 84.26 kB

Significant size changes

Includes any change greater than 0.2%:

(No significant changes)

Generated by 🚫 dangerJS against 98bb822

@gnoff
Copy link
Collaborator Author

gnoff commented Jul 21, 2022

Would it be better to warn when rendering <html> without a <head> child

In the short term that may be a better route to go in. Longer term there are plans to allow rendering heads late and so knowing when to warn or not warn is much harder b/c the head may come later in a boundary's contents that has not yet flushed. In this world there is going to need to be production code to handle hydration of <head> anyway.

I wonder how common this going to be in sizable projects though since almost everyone who is rendering a the root is going to want to put something in the head :)

@sophiebits
Copy link
Collaborator

Given the async nature I guess the warning could be for a <body> without a <head> then. Though I thought that typically the whole shell would come in at the same time including some the body content. Is there a point to rendering the opening <html> tag without any other content?

@gnoff
Copy link
Collaborator Author

gnoff commented Jul 21, 2022

It will probably be user controllable but yes there will be a way to flush <html> before the shell is ready so we can emit preload and preinit links. In this case we would need to emit a head though so we will have some notion of a default head which can be patched up by a late head if needed. The reason this won’t be automatic is that some users may want to emit error status codes if the shell errors and if we emit the head early something else like meta noindex would potentially be needed

When the browser parses html it will create a <head> element even if the tag is not present. If you render at the root (either the document itself or the html element) the hydration will fail becasue this implicitly created head is not matched against the react component tree. Additionally the head will be removed from the document as an extraneous node which means any third party scripts or other tags that were inserted there by browser extensions or other means will be deleted which can break many tools.

This change adds the ability to mark certain instances as implicit and so after attempting to hydrate them they will be skipped over rather than dropped.
@gnoff
Copy link
Collaborator Author

gnoff commented Oct 20, 2022

Closing in lieu of HostSingletons making this not necessary

@gnoff gnoff closed this Oct 20, 2022
@gnoff gnoff deleted the implicit-head-hydration branch January 11, 2023 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants