@samitouri / QOS-React / commits / dc6a7e01e1

[Float] Don't preload images inside `<noscript>` (#28815)

`<noscript>` scopes should be considered inert from the perspective of Fizz since we assume they'll only be used in rare and adverse circumstances. When we added preload support for img tags we did not include the noscript scope check in the opt-out for preloading. This change adds it in fixes: #27910

Josh Story committed Apr 10, 2024 at 12:15 UTC dc6a7e01e1d2fa5eb4974f9bb66e9e8fb40f6ef8
2 files changed +35 -3
packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+3 -3
@@ -2762,7 +2762,7 @@ function pushImg(
2762 props: Object,
2763 resumableState: ResumableState,
2764 renderState: RenderState,
2765 - pictureTagInScope: boolean,
2765 + pictureOrNoScriptTagInScope: boolean,
2766 ): null {
2767 const {src, srcSet} = props;
2768 if (
@@ -2771,7 +2771,7 @@ function pushImg(
2771 (typeof src === 'string' || src == null) &&
2772 (typeof srcSet === 'string' || srcSet == null) &&
2773 props.fetchPriority !== 'low' &&
2774 - pictureTagInScope === false &&
2774 + pictureOrNoScriptTagInScope === false &&
2775 // We exclude data URIs in src and srcSet since these should not be preloaded
2776 !(
2777 typeof src === 'string' &&
@@ -3599,7 +3599,7 @@ export function pushStartInstance(
3599 props,
3600 resumableState,
3601 renderState,
3602 - !!(formatContext.tagScope & PICTURE_SCOPE),
3602 + !!(formatContext.tagScope & (PICTURE_SCOPE | NOSCRIPT_SCOPE)),
3603 );
3604 }
3605 // Omitted close tags
packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+32
@@ -4261,6 +4261,38 @@ body {
4261 );
4262 });
4263
4264 + // Fixes: https://github.com/facebook/react/issues/27910
4265 + it('omits preloads for images inside noscript tags', async () => {
4266 + function App() {
4267 + return (
4268 + <html>
4269 + <body>
4270 + <img src="foo" />
4271 + <noscript>
4272 + <img src="bar" />
4273 + </noscript>
4274 + </body>
4275 + </html>
4276 + );
4277 + }
4278 +
4279 + await act(() => {
4280 + renderToPipeableStream(<App />).pipe(writable);
4281 + });
4282 +
4283 + expect(getMeaningfulChildren(document)).toEqual(
4284 + <html>
4285 + <head>
4286 + <link rel="preload" href="foo" as="image" />
4287 + </head>
4288 + <body>
4289 + <img src="foo" />
4290 + <noscript>&lt;img src="bar"&gt;</noscript>
4291 + </body>
4292 + </html>,
4293 + );
4294 + });
4295 +
4296 it('should handle media on image preload', async () => {
4297 function App({isClient}) {
4298 ReactDOM.preload('/server', {