react icon indicating copy to clipboard operation
react copied to clipboard

Support implicit <head> in hydration

Open gnoff opened this issue 1 year ago • 5 comments

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.

gnoff avatar Jul 21 '22 18:07 gnoff

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.

sophiebits avatar Jul 21 '22 19:07 sophiebits

Comparing: 3ddbedd0520a9738d8c3c7ce0268542e02f9738a...98bb822569ba3697f0531b0f7668143d192250ac

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 :no_entry_sign: dangerJS against 98bb822569ba3697f0531b0f7668143d192250ac

sizebot avatar Jul 21 '22 19:07 sizebot

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 :)

gnoff avatar Jul 21 '22 19:07 gnoff

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?

sophiebits avatar Jul 21 '22 19:07 sophiebits

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

gnoff avatar Jul 21 '22 19:07 gnoff

Closing in lieu of HostSingletons making this not necessary

gnoff avatar Oct 20 '22 23:10 gnoff