Skip to content

Commit 3706edb

Browse files
authored
[Float][Fizz]: Don't preload nomodule scripts (#26353)
We attempt to preload scripts that we detect during Fizz rendering however when `noModule={true}` we should not because it will force modern browser to fetch scripts they will never execute Hoisted script resources already don't preload because we just emit the resource immediately. This change currently on affects the preloads for scripts that aren't hoistable
1 parent 2b003a5 commit 3706edb

File tree

2 files changed

+44
-18
lines changed

2 files changed

+44
-18
lines changed

packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,25 +2056,28 @@ function pushScript(
20562056
const src = props.src;
20572057
const key = getResourceKey('script', src);
20582058
if (props.async !== true || props.onLoad || props.onError) {
2059-
// We can't resourcify scripts with load listeners. To avoid ambiguity with
2060-
// other Resourcified async scripts on the server we omit them from the server
2061-
// stream and expect them to be inserted during hydration on the client.
2062-
// We can still preload them however so the client can start fetching the script
2063-
// as soon as possible
2064-
let resource = resources.preloadsMap.get(key);
2065-
if (!resource) {
2066-
resource = {
2067-
type: 'preload',
2068-
chunks: [],
2069-
state: NoState,
2070-
props: preloadAsScriptPropsFromProps(props.src, props),
2071-
};
2072-
resources.preloadsMap.set(key, resource);
2073-
if (__DEV__) {
2074-
markAsImplicitResourceDEV(resource, props, resource.props);
2059+
// we don't want to preload nomodule scripts
2060+
if (props.noModule !== true) {
2061+
// We can't resourcify scripts with load listeners. To avoid ambiguity with
2062+
// other Resourcified async scripts on the server we omit them from the server
2063+
// stream and expect them to be inserted during hydration on the client.
2064+
// We can still preload them however so the client can start fetching the script
2065+
// as soon as possible
2066+
let resource = resources.preloadsMap.get(key);
2067+
if (!resource) {
2068+
resource = {
2069+
type: 'preload',
2070+
chunks: [],
2071+
state: NoState,
2072+
props: preloadAsScriptPropsFromProps(props.src, props),
2073+
};
2074+
resources.preloadsMap.set(key, resource);
2075+
if (__DEV__) {
2076+
markAsImplicitResourceDEV(resource, props, resource.props);
2077+
}
2078+
resources.usedScripts.add(resource);
2079+
pushLinkImpl(resource.chunks, resource.props);
20752080
}
2076-
resources.usedScripts.add(resource);
2077-
pushLinkImpl(resource.chunks, resource.props);
20782081
}
20792082

20802083
if (props.async !== true) {

packages/react-dom/src/__tests__/ReactDOMFloat-test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,6 +2639,29 @@ body {
26392639
);
26402640
});
26412641

2642+
it('does not preload nomodule scripts', async () => {
2643+
await actIntoEmptyDocument(() => {
2644+
renderToPipeableStream(
2645+
<html>
2646+
<body>
2647+
<script src="foo" noModule={true} data-meaningful="" />
2648+
<script async={true} src="bar" noModule={true} data-meaningful="" />
2649+
</body>
2650+
</html>,
2651+
).pipe(writable);
2652+
});
2653+
expect(getMeaningfulChildren(document)).toEqual(
2654+
<html>
2655+
<head>
2656+
<script async="" src="bar" nomodule="" data-meaningful="" />
2657+
</head>
2658+
<body>
2659+
<script src="foo" nomodule="" data-meaningful="" />
2660+
</body>
2661+
</html>,
2662+
);
2663+
});
2664+
26422665
describe('ReactDOM.prefetchDNS(href)', () => {
26432666
it('creates a dns-prefetch resource when called', async () => {
26442667
function App({url}) {

0 commit comments

Comments
 (0)