From 3706edb81c84ea01e68bfb477537ba9908e1bd70 Mon Sep 17 00:00:00 2001 From: Josh Story Date: Wed, 8 Mar 2023 21:59:43 -0800 Subject: [PATCH] [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 --- .../src/server/ReactDOMServerFormatConfig.js | 39 ++++++++++--------- .../src/__tests__/ReactDOMFloat-test.js | 23 +++++++++++ 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js b/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js index 77a7067e5d..09c879e8aa 100644 --- a/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js +++ b/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js @@ -2056,25 +2056,28 @@ function pushScript( const src = props.src; const key = getResourceKey('script', src); if (props.async !== true || props.onLoad || props.onError) { - // We can't resourcify scripts with load listeners. To avoid ambiguity with - // other Resourcified async scripts on the server we omit them from the server - // stream and expect them to be inserted during hydration on the client. - // We can still preload them however so the client can start fetching the script - // as soon as possible - let resource = resources.preloadsMap.get(key); - if (!resource) { - resource = { - type: 'preload', - chunks: [], - state: NoState, - props: preloadAsScriptPropsFromProps(props.src, props), - }; - resources.preloadsMap.set(key, resource); - if (__DEV__) { - markAsImplicitResourceDEV(resource, props, resource.props); + // we don't want to preload nomodule scripts + if (props.noModule !== true) { + // We can't resourcify scripts with load listeners. To avoid ambiguity with + // other Resourcified async scripts on the server we omit them from the server + // stream and expect them to be inserted during hydration on the client. + // We can still preload them however so the client can start fetching the script + // as soon as possible + let resource = resources.preloadsMap.get(key); + if (!resource) { + resource = { + type: 'preload', + chunks: [], + state: NoState, + props: preloadAsScriptPropsFromProps(props.src, props), + }; + resources.preloadsMap.set(key, resource); + if (__DEV__) { + markAsImplicitResourceDEV(resource, props, resource.props); + } + resources.usedScripts.add(resource); + pushLinkImpl(resource.chunks, resource.props); } - resources.usedScripts.add(resource); - pushLinkImpl(resource.chunks, resource.props); } if (props.async !== true) { diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js index 4c503bbe29..773944db3d 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js @@ -2639,6 +2639,29 @@ body { ); }); + it('does not preload nomodule scripts', async () => { + await actIntoEmptyDocument(() => { + renderToPipeableStream( + + +