Skip to content

Commit

Permalink
Add support for preload media to ReactDOM (#28635)
Browse files Browse the repository at this point in the history
This PR adds support for `media` option to `ReactDOM.preload()`, which
is needed when images differ between screen sizes (for example mobile vs
desktop)
  • Loading branch information
mariusc23 committed Mar 28, 2024
1 parent 05797cc commit 78328c0
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
85 changes: 85 additions & 0 deletions packages/react-dom/src/__tests__/ReactDOMFloat-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4261,6 +4261,91 @@ body {
);
});

it('should handle media on image preload', async () => {
function App({isClient}) {
ReactDOM.preload('/server', {
as: 'image',
imageSrcSet: '/server',
imageSizes: '100vw',
media: 'print and (min-width: 768px)',
});

if (isClient) {
ReactDOM.preload('/client', {
as: 'image',
imageSrcSet: '/client',
imageSizes: '100vw',
media: 'screen and (max-width: 480px)',
});
}

return (
<html>
<body>hello</body>
</html>
);
}

await act(() => {
renderToPipeableStream(<App />).pipe(writable);
});
expect(getMeaningfulChildren(document)).toEqual(
<html>
<head>
<link
rel="preload"
as="image"
imagesrcset="/server"
imagesizes="100vw"
media="print and (min-width: 768px)"
/>
</head>
<body>hello</body>
</html>,
);

const root = ReactDOMClient.hydrateRoot(document, <App />);
await waitForAll([]);
expect(getMeaningfulChildren(document)).toEqual(
<html>
<head>
<link
rel="preload"
as="image"
imagesrcset="/server"
imagesizes="100vw"
media="print and (min-width: 768px)"
/>
</head>
<body>hello</body>
</html>,
);

root.render(<App isClient={true} />);
await waitForAll([]);
expect(getMeaningfulChildren(document)).toEqual(
<html>
<head>
<link
rel="preload"
as="image"
imagesrcset="/server"
imagesizes="100vw"
media="print and (min-width: 768px)"
/>
<link
rel="preload"
as="image"
imagesrcset="/client"
imagesizes="100vw"
media="screen and (max-width: 480px)"
/>
</head>
<body>hello</body>
</html>,
);
});

it('should warn if you preload a stylesheet and then render a style tag with the same href', async () => {
const style = 'body { color: red; }';
function App() {
Expand Down
1 change: 1 addition & 0 deletions packages/react-dom/src/shared/ReactDOMFloat.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export function preload(href: string, options: PreloadOptions) {
: undefined,
imageSizes:
typeof options.imageSizes === 'string' ? options.imageSizes : undefined,
media: typeof options.media === 'string' ? options.media : undefined,
});
}
// We don't error because preload needs to be resilient to being called in a variety of scopes
Expand Down
1 change: 1 addition & 0 deletions packages/react-dom/src/shared/ReactDOMTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type PreloadOptions = {
crossOrigin?: string,
integrity?: string,
type?: string,
media?: string,
nonce?: string,
fetchPriority?: FetchPriorityEnum,
imageSrcSet?: string,
Expand Down

0 comments on commit 78328c0

Please sign in to comment.