Skip to content

Commit

Permalink
fix(next/image): priority in App Router causes double fetch on mobile (
Browse files Browse the repository at this point in the history
…vercel#53700)

The root cause is `ReactDOM.preload()` inserts `<link rel="preload">` above the `<meta name="viewport">`. 

This PR adds a test to prove that upgrading React fixes the issue (see commits).

- Depends on facebook/react#27201
- Depends on vercel#53742
- Fixes vercel#53574
- Related vercel#52995
  • Loading branch information
styfle committed Aug 8, 2023
1 parent f0dab3a commit 195d1f1
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const Page = () => {
return (
<div>
<h1 id="page-header">Static Image</h1>
<Image id="basic-static" src={testImg} placeholder="blur" />
<Image id="basic-static" src={testImg} placeholder="blur" priority />
<TallImage />
<Image
id="defined-width-and-height"
Expand Down
24 changes: 24 additions & 0 deletions test/integration/next-image-new/app-dir/test/static.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@ const runTests = (isDev) => {
)
})
}
it('should have <head> containing <meta name="viewport"> followed by <link rel="preload"> for priority image', async () => {
let metaViewport = { index: 0, attribs: {} as any }
let linkPreload = { index: 0, attribs: {} as any }
$('head')
.children()
.toArray()
.forEach((child, index) => {
const { tagName, attribs } = child
if (tagName === 'meta' && attribs.name === 'viewport') {
metaViewport = { index, attribs }
} else if (
tagName === 'link' &&
attribs.rel === 'preload' &&
attribs.as === 'image'
) {
linkPreload = { index, attribs }
}
})
expect(metaViewport.attribs.content).toContain('width=device-width')
expect(linkPreload.attribs.imagesrcset).toContain(
'%2F_next%2Fstatic%2Fmedia%2Ftest-rect.f323a148.jpg'
)
expect(metaViewport.index).toBeLessThan(linkPreload.index)
})
it('Should automatically provide an image height and width', async () => {
const img = $('#basic-non-static')
expect(img.attr('width')).toBe('400')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Page = () => {
return (
<div>
<h1 id="page-header">Static Image</h1>
<Image id="basic-static" src={testImg} placeholder="blur" />
<Image id="basic-static" src={testImg} placeholder="blur" priority />
<TallImage />
<Image
id="defined-width-and-height"
Expand Down
24 changes: 24 additions & 0 deletions test/integration/next-image-new/base-path/test/static.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ const runTests = (isDev) => {
)
})
}
it('should have <head> containing <meta name="viewport"> followed by <link rel="preload"> for priority image', async () => {
let metaViewport = { index: 0, attribs: {} }
let linkPreload = { index: 0, attribs: {} }
$('head')
.children()
.toArray()
.forEach((child, index) => {
const { tagName, attribs } = child
if (tagName === 'meta' && attribs.name === 'viewport') {
metaViewport = { index, attribs }
} else if (
tagName === 'link' &&
attribs.rel === 'preload' &&
attribs.as === 'image'
) {
linkPreload = { index, attribs }
}
})
expect(metaViewport.attribs.content).toContain('width=device-width')
expect(linkPreload.attribs.imagesrcset).toContain(
'%2F_next%2Fstatic%2Fmedia%2Ftest-rect.f323a148.jpg'
)
expect(metaViewport.index).toBeLessThan(linkPreload.index)
})
it('Should automatically provide an image height and width', async () => {
const img = $('#basic-non-static')
expect(img.attr('width')).toBe('400')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Page = ({ testImgProp }) => {
return (
<div>
<h1 id="page-header">Static Image</h1>
<Image id="basic-static" src={testImg} placeholder="blur" />
<Image id="basic-static" src={testImg} placeholder="blur" priority />
<Image id="basic-staticprop" src={testImgProp} placeholder="blur" />
<TallImage />
<Image
Expand Down
24 changes: 24 additions & 0 deletions test/integration/next-image-new/default/test/static.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,30 @@ const runTests = (isDev) => {
)
})
}
it('should have <head> containing <meta name="viewport"> followed by <link rel="preload"> for priority image', async () => {
let metaViewport = { index: 0, attribs: {} as any }
let linkPreload = { index: 0, attribs: {} as any }
$('head')
.children()
.toArray()
.forEach((child, index) => {
const { tagName, attribs } = child
if (tagName === 'meta' && attribs.name === 'viewport') {
metaViewport = { index, attribs }
} else if (
tagName === 'link' &&
attribs.rel === 'preload' &&
attribs.as === 'image'
) {
linkPreload = { index, attribs }
}
})
expect(metaViewport.attribs.content).toContain('width=device-width')
expect(linkPreload.attribs.imagesrcset).toContain(
'%2F_next%2Fstatic%2Fmedia%2Ftest-rect.f323a148.jpg'
)
expect(metaViewport.index).toBeLessThan(linkPreload.index)
})
it('Should automatically provide an image height and width', async () => {
const img = $('#basic-non-static')
expect(img.attr('width')).toBe('400')
Expand Down

0 comments on commit 195d1f1

Please sign in to comment.