Repository: facebook/react
Pull request: [Float][Fizz] Fix srcSet and sizes handling for suspensey img preloads

imageSrcSet should have been srcSet when referencing an img tag. imageSizes should have been sizes. This caused preloads for img tags using srcSet and sizes to incorrectly render as having a href only, dropping the srcSet and sizes part of the preload


Changed files:
filename: packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
patch: @@ -2399,8 +2399,8 @@ function pushImg(
   ) {
     // We have a suspensey image and ought to preload it to optimize the loading of display blocking
     // resources.
-    const {src, imageSrcSet, imageSizes} = props;
-    const key = getImagePreloadKey(src, imageSrcSet, imageSizes);
+    const {src, srcSet, sizes} = props;
+    const key = getImagePreloadKey(src, srcSet, sizes);
     let resource = resources.preloadsMap.get(key);
     if (!resource) {
       resource = {
@@ -2414,9 +2414,9 @@ function pushImg(
           // so we omit the href here if we have imageSrcSet b/c safari will load the wrong image.
           // This harms older browers that do not support imageSrcSet by making their preloads not work
           // but this population is shrinking fast and is already small so we accept this tradeoff.
-          href: imageSrcSet ? undefined : src,
-          imageSrcSet,
-          imageSizes,
+          href: srcSet ? undefined : src,
+          imageSrcSet: srcSet,
+          imageSizes: sizes,
           crossOrigin: props.crossOrigin,
           integrity: props.integrity,
           type: props.type,

filename: packages/react-dom/src/__tests__/ReactDOMFloat-test.js
patch: @@ -3782,9 +3782,9 @@ body {
             <img src="a" />
             <img src="b" loading="lazy" />
             <img src="b2" loading="lazy" />
-            <img src="c" imageSrcSet="srcsetc" />
-            <img src="d" imageSrcSet="srcsetd" imageSizes="sizesd" />
-            <img src="d" imageSrcSet="srcsetd" imageSizes="sizesd2" />
+            <img src="c" srcSet="srcsetc" />
+            <img src="d" srcSet="srcsetd" sizes="sizesd" />
+            <img src="d" srcSet="srcsetd" sizes="sizesd2" />
           </body>
         </html>
       );
@@ -3819,9 +3819,9 @@ body {
           <img src="a" />
           <img src="b" loading="lazy" />
           <img src="b2" loading="lazy" />
-          <img src="c" imagesrcset="srcsetc" />
-          <img src="d" imagesrcset="srcsetd" imagesizes="sizesd" />
-          <img src="d" imagesrcset="srcsetd" imagesizes="sizesd2" />
+          <img src="c" srcset="srcsetc" />
+          <img src="d" srcset="srcsetd" sizes="sizesd" />
+          <img src="d" srcset="srcsetd" sizes="sizesd2" />
         </body>
       </html>,
     );
@@ -3928,6 +3928,47 @@ body {
     );
   });
 
+  it('preloads from rendered images properly use srcSet and sizes', async () => {
+    function App() {
+      ReactDOM.preload('1', {as: 'image', imageSrcSet: 'ss1'});
+      ReactDOM.preload('2', {
+        as: 'image',
+        imageSrcSet: 'ss2',
+        imageSizes: 's2',
+      });
+      return (
+        <html>
+          <body>
+            <img src="1" srcSet="ss1" />
+            <img src="2" srcSet="ss2" sizes="s2" />
+            <img src="3" srcSet="ss3" />
+            <img src="4" srcSet="ss4" sizes="s4" />
+          </body>
+        </html>
+      );
+    }
+    await act(() => {
+      renderToPipeableStream(<App />).pipe(writable);
+    });
+
+    expect(getMeaningfulChildren(document)).toEqual(
+      <html>
+        <head>
+          <link rel="preload" as="image" imagesrcset="ss1" />
+          <link rel="preload" as="image" imagesrcset="ss2" imagesizes="s2" />
+          <link rel="preload" as="image" imagesrcset="ss3" />
+          <link rel="preload" as="image" imagesrcset="ss4" imagesizes="s4" />
+        </head>
+        <body>
+          <img src="1" srcset="ss1" />
+          <img src="2" srcset="ss2" sizes="s2" />
+          <img src="3" srcset="ss3" />
+          <img src="4" srcset="ss4" sizes="s4" />
+        </body>
+      </html>,
+    );
+  });
+
   describe('ReactDOM.prefetchDNS(href)', () => {
     it('creates a dns-prefetch resource when called', async () => {
       function App({url}) {