[Fizz] Deduplicate <link rel="preload"> from Flight preload hints#607
[Fizz] Deduplicate <link rel="preload"> from Flight preload hints#607everettbu wants to merge 1 commit into
<link rel="preload"> from Flight preload hints#607Conversation
…nt preload duplication
Greptile SummaryThis PR fixes a duplicate
Confidence Score: 4/5
Important Files Changed
Last reviewed commit: 3968a8d |
| if (resumableState.imageResources.hasOwnProperty(key)) { | ||
| return null; | ||
| } | ||
| resumableState.imageResources[key] = PRELOAD_NO_CREDS; |
There was a problem hiding this comment.
Credentials not preserved for style/script preloads
For as="style" and as="script", the preload() function (lines 6470-6475, 6493-6498) conditionally stores [options.crossOrigin, options.integrity] when those props are present, so that later <link rel="stylesheet"> or <script> elements can adopt those credentials via adoptPreloadCredentials(). Here, all resource types unconditionally store PRELOAD_NO_CREDS.
This means if a <link rel="preload" as="style" crossorigin="anonymous" integrity="sha256-..."> is rendered in RSC and registers here before the Flight hint's preload() call, the credential information is lost in resumableState. A later <link rel="stylesheet"> for the same href would not be able to adopt crossOrigin/integrity from the preload state (the check at line 2952 preloadState.length === 2 would fail).
In practice this is likely low-impact since the <link> element itself will still be in the HTML with the correct attributes, and stylesheets typically carry their own credentials. But for consistency with the preload() API, the style and script cases could store credential info from props.crossOrigin and props.integrity when present.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
Line: 3041
Comment:
**Credentials not preserved for style/script preloads**
For `as="style"` and `as="script"`, the `preload()` function (lines 6470-6475, 6493-6498) conditionally stores `[options.crossOrigin, options.integrity]` when those props are present, so that later `<link rel="stylesheet">` or `<script>` elements can adopt those credentials via `adoptPreloadCredentials()`. Here, all resource types unconditionally store `PRELOAD_NO_CREDS`.
This means if a `<link rel="preload" as="style" crossorigin="anonymous" integrity="sha256-...">` is rendered in RSC and registers here before the Flight hint's `preload()` call, the credential information is lost in `resumableState`. A later `<link rel="stylesheet">` for the same `href` would not be able to adopt `crossOrigin`/`integrity` from the preload state (the check at line 2952 `preloadState.length === 2` would fail).
In practice this is likely low-impact since the `<link>` element itself will still be in the HTML with the correct attributes, and stylesheets typically carry their own credentials. But for consistency with the `preload()` API, the `style` and `script` cases could store credential info from `props.crossOrigin` and `props.integrity` when present.
How can I resolve this? If you propose a fix, please make it concise.<link rel="preload"> from Flight preload hints
Mirror of facebook/react#35892
Original author: lllomh
Summary
Fixes #35889
<link rel="preload" as="font" />(and other preload types) renderedinside an RSC component was appearing twice in SSR HTML when used
with Fizz SSR. This regression was introduced in 19.2.
Root cause:
When the RSC Flight server processes a
<link rel="preload">element, itdoes two things:
'L'row) viaprocessLink()inReactFlightServerConfigDOM.js<link>element in the serialized component outputDuring Fizz SSR, the Flight hint is received and dispatched to the Fizz
preload()function, which registers the resource inresumableStateand adds it to
renderState.fontPreloads. Later, the same<link>element from the component output is processed by
pushLink(), whichfell through to
pushLinkImpl(renderState.hoistableChunks, props)withno deduplication check — producing a second identical link tag.
Fix:
In
pushLink(), before emitting a<link rel="preload">tohoistableChunks, check whether the resource is already registered inresumableState(using the same per-as-type tracking thatpreload()uses:
imageResources,styleResources,scriptResources, andunknownResourcesfor fonts and others). If already registered, returnnull. If not yet registered, register it so futurepreload()callswill also deduplicate correctly.
Test plan
does not duplicate font preload links from Flight hints during Fizz SSRinReactFlightDOM-test.jsthat rendersa
<link rel="preload" as="font">inside an RSC component through FizzSSR and asserts the link appears exactly once in the HTML output.