@samitouri / QOS-React-2 / commits / 4e3618ae41

[Float][Fizz] Fix srcSet and sizes handling for suspensey img preloads (#27217)

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

Josh Story committed Aug 11, 2023 at 11:27 UTC 4e3618ae41669c95a3377ae615c727f74f89d141
2 files changed +52 -11
packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+5 -5
@@ -2399,8 +2399,8 @@ function pushImg(
2399 ) {
2400 // We have a suspensey image and ought to preload it to optimize the loading of display blocking
2401 // resources.
2402 - const {src, imageSrcSet, imageSizes} = props;
2403 - const key = getImagePreloadKey(src, imageSrcSet, imageSizes);
2402 + const {src, srcSet, sizes} = props;
2403 + const key = getImagePreloadKey(src, srcSet, sizes);
2404 let resource = resources.preloadsMap.get(key);
2405 if (!resource) {
2406 resource = {
@@ -2414,9 +2414,9 @@ function pushImg(
2414 // so we omit the href here if we have imageSrcSet b/c safari will load the wrong image.
2415 // This harms older browers that do not support imageSrcSet by making their preloads not work
2416 // but this population is shrinking fast and is already small so we accept this tradeoff.
2417 - href: imageSrcSet ? undefined : src,
2418 - imageSrcSet,
2419 - imageSizes,
2417 + href: srcSet ? undefined : src,
2418 + imageSrcSet: srcSet,
2419 + imageSizes: sizes,
2420 crossOrigin: props.crossOrigin,
2421 integrity: props.integrity,
2422 type: props.type,
packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+47 -6
@@ -3782,9 +3782,9 @@ body {
3782 <img src="a" />
3783 <img src="b" loading="lazy" />
3784 <img src="b2" loading="lazy" />
3785 - <img src="c" imageSrcSet="srcsetc" />
3786 - <img src="d" imageSrcSet="srcsetd" imageSizes="sizesd" />
3787 - <img src="d" imageSrcSet="srcsetd" imageSizes="sizesd2" />
3785 + <img src="c" srcSet="srcsetc" />
3786 + <img src="d" srcSet="srcsetd" sizes="sizesd" />
3787 + <img src="d" srcSet="srcsetd" sizes="sizesd2" />
3788 </body>
3789 </html>
3790 );
@@ -3819,9 +3819,9 @@ body {
3819 <img src="a" />
3820 <img src="b" loading="lazy" />
3821 <img src="b2" loading="lazy" />
3822 - <img src="c" imagesrcset="srcsetc" />
3823 - <img src="d" imagesrcset="srcsetd" imagesizes="sizesd" />
3824 - <img src="d" imagesrcset="srcsetd" imagesizes="sizesd2" />
3822 + <img src="c" srcset="srcsetc" />
3823 + <img src="d" srcset="srcsetd" sizes="sizesd" />
3824 + <img src="d" srcset="srcsetd" sizes="sizesd2" />
3825 </body>
3826 </html>,
3827 );
@@ -3928,6 +3928,47 @@ body {
3928 );
3929 });
3930
3931 + it('preloads from rendered images properly use srcSet and sizes', async () => {
3932 + function App() {
3933 + ReactDOM.preload('1', {as: 'image', imageSrcSet: 'ss1'});
3934 + ReactDOM.preload('2', {
3935 + as: 'image',
3936 + imageSrcSet: 'ss2',
3937 + imageSizes: 's2',
3938 + });
3939 + return (
3940 + <html>
3941 + <body>
3942 + <img src="1" srcSet="ss1" />
3943 + <img src="2" srcSet="ss2" sizes="s2" />
3944 + <img src="3" srcSet="ss3" />
3945 + <img src="4" srcSet="ss4" sizes="s4" />
3946 + </body>
3947 + </html>
3948 + );
3949 + }
3950 + await act(() => {
3951 + renderToPipeableStream(<App />).pipe(writable);
3952 + });
3953 +
3954 + expect(getMeaningfulChildren(document)).toEqual(
3955 + <html>
3956 + <head>
3957 + <link rel="preload" as="image" imagesrcset="ss1" />
3958 + <link rel="preload" as="image" imagesrcset="ss2" imagesizes="s2" />
3959 + <link rel="preload" as="image" imagesrcset="ss3" />
3960 + <link rel="preload" as="image" imagesrcset="ss4" imagesizes="s4" />
3961 + </head>
3962 + <body>
3963 + <img src="1" srcset="ss1" />
3964 + <img src="2" srcset="ss2" sizes="s2" />
3965 + <img src="3" srcset="ss3" />
3966 + <img src="4" srcset="ss4" sizes="s4" />
3967 + </body>
3968 + </html>,
3969 + );
3970 + });
3971 +
3972 describe('ReactDOM.prefetchDNS(href)', () => {
3973 it('creates a dns-prefetch resource when called', async () => {
3974 function App({url}) {