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

Initial docs for DOM static resource loading functions #6459

Merged
merged 3 commits into from
Feb 2, 2024

Conversation

davidmccabe
Copy link
Contributor

@davidmccabe davidmccabe commented Dec 2, 2023

Add docs for the Float imperative functions: preconnect, prefetchDNS, preinit, preinitModule, preload, preloadModule.

@gnoff Please read with a close eye for accuracy.

https://react-dev-git-fork-davidmccabe-float2-fbopensource.vercel.app/reference/react-dom#resource-preloading-apis

I think these are still canary only, is that correct?

Copy link

github-actions bot commented Dec 2, 2023

Size changes

📦 Next.js Bundle Analysis for react-dev

This analysis was generated by the Next.js Bundle Analysis action. 🤖

One Page Changed Size

The following page changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load
/[[...markdownPath]] 79.01 KB (🟡 +61 B) 182.82 KB
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 10% or more, there will be a red status indicator applied, indicating that special attention should be given to this.

Copy link
Collaborator

@gnoff gnoff left a comment

Choose a reason for hiding this comment

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

Going to keep reviewing but so far I've taken a look at the index and preload pages.

One question I have is whether we should convey the idea that for users of libraries and meta frameworks it is likely you don't need to call these preloading functions yourself becuase the tool you are using is probably doing it for you?

If you roll your own resource loading in React then these methods are useful
If you write libraries that manage resource loading then these methods are useful
But for likely the large majority of React developers these methods will probably not get used.

One case that may be more common is libraries probalby cannot reason about the domains you are likely to connect to so probably won't use preconnect and prefetchDNS much however App authors have this information. This may be the most commonly used methods by non-library/non-metaframework authors even if it seems like the least powerful

Comment on lines 24 to 29
* [`preload`](/reference/react-dom/preload) lets you fetch a stylesheet, font, image, or external script that you expect to use.
* [`preloadModule`](/reference/react-dom/preloadModule) lets you fetch an ESM module that you expect to use.
* [`preinit`](/reference/react-dom/preinit) lets you fetch and evaluate an external script or fetch and insert a stylesheet.
* [`preinitModule`](/reference/react-dom/preinitModule) lets you fetch and evaluate an ESM module.
* [`prefetchDNS`](/reference/react-dom/prefetchDNS) lets you prefetch the IP address of a DNS domain name that you expect to connect to.
* [`preconnect`](/reference/react-dom/preconnect) lets you connect to a server you expect to request resources from, even if you don't know what resources you'll need yet.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure what the best way to order these. In my head there is a hierarchy of levels of loading/connecting

prefetchDNS will make a DNS lookup for a domain, pretty minimal, operates at the hostname level
preconnect will open a connection, still minimal, operates at the hostname level and varies by crossOrigin (because browser connections do too)

preload/preloadModul will load the resource but not actually use the resource. If the resource is used by the browser later it should be able to avoid fetching the resource again. Operates at a URL level (with some nuance around image src sets

preinit/preinitModule will load the resource and actually use it. For stylesheets this means the style rules will be applied to the document as soon as it loads. For scripts this means the script will execute once it loads. This also operates at the level of a URL


* `href`: a string. The URL of the resource you want to download.
* `options`: an object. It contains the following properties:
* `as`: a required string. The type of resource. Its possible values are `audio`, `document`, `embed`, `fetch`, `font`, `image`, `object`, `script`, `style`, `track`, `video`, `worker`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

The intended support semantics here are anything that a browser can preload. also the as property is named such because this maps to the as attribute of a <link rel="preload"... tag. Maybe we should clarify where the list of supported types comes from so if/when it evolves it's clear React's implementation will as well?

Maybe link to the relevant MDN documentation?

@sophiebits sophiebits changed the title Initial docs for Float functions Initial docs for DOM static resource loading functions Dec 19, 2023
@githrdw
Copy link

githrdw commented Dec 30, 2023

I was looking for this documentation!
Let me explain my use case to hopefully give more priority to this documentation :)
We are using Next.JS (14.0.5-canary.5) with React (18.2.0) and have tried using the Image component.
It contains a preload function and all kinds of niceties about srcset.

However, it did not meet our requirements, because it does not work with our WordPress API / CDN setup.
We are tied to use <picture> with <source>'s because of our complicated art direction, instead of Next's <img> with sizes.
This means that we also have to take care of our own image preload.

Next briefly noticed this preload function in it's meta docs, but not all of the options.
It's thanks to TS I discovered the preload options are available, as Next and React did not document those yet.

@githrdw
Copy link

githrdw commented Dec 30, 2023

In addition, I feel free to draw attention to this PR:
facebook/react#27129

Adding media option to preload function.

The component I am working on is a hero image (LCP) and must therefore be preloaded with the highest priority.
The preload also needs to know which <source> is loaded into <picture>, depending on the media query.
This preload media query cannot yet be configured in any way.


* `href`: a string. The URL of the resource you want to download and execute.
* `options`: an object. It contains the following properties:
* `as`: a required string. The type of resource. Its possible values are `script` and `style`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* `as`: a required string. The type of resource. Its possible values are `script` and `style`.
* `as`: a required string. The type of resource. Its possible values are `script` and `style`.

* `options`: an object. It contains the following properties:
* `as`: a required string. The type of resource. Its possible values are `script` and `style`.
* `precedence`: a string. Required with stylesheets. Says where to insert the stylesheet relative to others. Stylesheets with higher precedence can override those with lower precedence. The possible values are `reset`, `low`, `medium`, `high`.
* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.
* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.

* `as`: a required string. The type of resource. Its possible values are `script` and `style`.
* `precedence`: a string. Required with stylesheets. Says where to insert the stylesheet relative to others. Stylesheets with higher precedence can override those with lower precedence. The possible values are `reset`, `low`, `medium`, `high`.
* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.
* `integrity`: a string. A cryptographic hash of the resource, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* `integrity`: a string. A cryptographic hash of the resource, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
* `integrity`: a string. A cryptographic hash of the resource, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).

* `options`: an object. It contains the following properties:
* `as`: a required string. The type of resource. Its possible values are `script` and `style`.
* `precedence`: a string. Required with stylesheets. Says where to insert the stylesheet relative to others. Stylesheets with higher precedence can override those with lower precedence. The possible values are `reset`, `low`, `medium`, `high`.
* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.
Copy link
Contributor

Choose a reason for hiding this comment

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

It is required when as is set to "fetch".

vs

  • as: a required string. The type of resource. Its possible values are script and style.

Need more clarification whether fetch is a possible value of as or not.

* `precedence`: a string. Required with stylesheets. Says where to insert the stylesheet relative to others. Stylesheets with higher precedence can override those with lower precedence. The possible values are `reset`, `low`, `medium`, `high`.
* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.
* `integrity`: a string. A cryptographic hash of the resource, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
* `nonce`: a string. A cryptographic [nonce to allow the resource](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* `nonce`: a string. A cryptographic [nonce to allow the resource](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy.
* `nonce`: a string. A cryptographic [nonce to allow the resource](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy.

* `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`.
* `integrity`: a string. A cryptographic hash of the resource, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).
* `nonce`: a string. A cryptographic [nonce to allow the resource](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy.
* `fetchPriority`: a string. Suggests a relative priority for fetching the resource. The possible values are `auto` (the default), `high`, and `low`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* `fetchPriority`: a string. Suggests a relative priority for fetching the resource. The possible values are `auto` (the default), `high`, and `low`.
* `fetchPriority`: a string. Suggests a relative priority for fetching the resource. The possible values are `auto` (the default), `high`, and `low`.


* Multiple calls to `preconnect` with the same server have the same effect as a single call.
* In the browser, you can call `preconnect` in any situation: while rendering a component, in an effect, in an event handler, and so on.
* In server-side rendering or when rendering Server Components, `preconnect` only has an effect if you call it while rendering a component or in an async context originating from rendering a component. Any other calls will be ignored.
Copy link
Contributor

Choose a reason for hiding this comment

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

an async context originating from rendering a component

I don't think it's obvious what this refers to. I think an example of one of these contexts would help here.

@rbalicki2
Copy link

rbalicki2 commented Jan 3, 2024

This isn't related to the documentation per se, but since these resources aren't disposable, perhaps the docs could include information about what one wants to do if one wants to avoid memory leaks? Is cleanup React's responsibility? Are these scoped to the tree from which preconnect etc. are called? Presumably not, since they seem to be callable imperatively?

In addition, what happens if the cryptographic hash doesn't match? Is this exposed to the user anywhere?

Lastly, I think the docs are a bit unclear about when a module is executed when one runs preloadModule. Is it executed when it is required? Loaded with lazy?

@davidmccabe davidmccabe merged commit 2372ecf into reactjs:main Feb 2, 2024
4 checks passed
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.

7 participants