[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}) {