Update default widths configuration to handle 2x/3x DPI (#18717)
- Update default `deviceSizes` - Add default `imageSizes` - Use `layout` value to determine which `srcset` to use Fixes #18420 Closes #18714
This commit is contained in:
parent
3f84a55ba3
commit
2b94b1eea6
11 changed files with 83 additions and 77 deletions
|
@ -46,8 +46,8 @@ export default Home
|
|||
`Image` accepts the following props:
|
||||
|
||||
- `src` - The path or URL to the source image. This is required.
|
||||
- `width` - The intrinsic width of the source image in pixels. Must be an integer without a unit. Required unless `layout="fill"`.
|
||||
- `height` - The intrinsic height of the source image, in pixels. Must be an integer without a unit. Required unless `layout="fill"`.
|
||||
- `width` - The width of the image, in pixels. Must be an integer without a unit. Required unless `layout="fill"`.
|
||||
- `height` - The height of the image, in pixels. Must be an integer without a unit. Required unless `layout="fill"`.
|
||||
- `layout` - The rendered layout of the image. If `fixed`, the image dimensions will not change as the viewport changes (no responsiveness). If `intrinsic`, the image will scale the dimensions down for smaller viewports but maintain the original dimensions for larger viewports. If `responsive`, the image will scale the dimensions down for smaller viewports and scale up for larger viewports. If `fill`, the image will stretch both width and height to the dimensions of the parent element. Default `intrinsic`.
|
||||
- `sizes` - Defines what proportion of the screen you expect the image to take up. Recommended, as it helps serve the correct sized image to each device. [More info](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes).
|
||||
- `quality` - The quality of the optimized image, an integer between 1 and 100 where 100 is the best quality. Default 75.
|
||||
|
|
|
@ -62,8 +62,8 @@ If no configuration is provided, the following default configuration will be use
|
|||
```js
|
||||
module.exports = {
|
||||
images: {
|
||||
deviceSizes: [320, 420, 768, 1024, 1200],
|
||||
imageSizes: [],
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
domains: [],
|
||||
path: '/_next/image',
|
||||
loader: 'default',
|
||||
|
@ -77,24 +77,24 @@ This means you only need to configure the properties you wish to change.
|
|||
|
||||
### Device Sizes
|
||||
|
||||
You can specify a list of device width breakpoints using the `deviceSizes` property. Since images maintain their aspect ratio using the `width` and `height` attributes of the source image, there is no need to specify height in `next.config.js` – only the width. These values will be used by the browser to determine which size image should load.
|
||||
You can specify a list of device width breakpoints using the `deviceSizes` property. These widths are used when the [`next/image`](/docs/api-reference/next/image.md) component uses `layout="responsive"` or `layout="fill"` so that the correct image is served for the device visiting your website.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
images: {
|
||||
deviceSizes: [320, 420, 768, 1024, 1200],
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Image Sizes
|
||||
|
||||
You can specify a list of exact image widths using the `imageSizes` property. These widths should be different than the widths defined in `deviceSizes`. The purpose is for images that don't scale with the browser window, such as icons, badges, or profile images. If the `width` property of a [`next/image`](/docs/api-reference/next/image.md) component matches a value in `imageSizes`, the image will be rendered at that exact width.
|
||||
You can specify a list of image widths using the `imageSizes` property. These widths should be different than the widths defined in `deviceSizes` because the arrays will be concatentated. These widths are used when the [`next/image`](/docs/api-reference/next/image.md) component uses `layout="fixed"` or `layout="intrinsic"`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
images: {
|
||||
imageSizes: [16, 32, 64],
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
@ -143,7 +143,7 @@ The expiration (or rather Max Age) is defined by the upstream server's `Cache-Co
|
|||
|
||||
If `s-maxage` is found in `Cache-Control`, it is used. If no `s-maxage` is found, then `max-age` is used. If no `max-age` is found, then 60 seconds is used.
|
||||
|
||||
You can configure [`deviceSizes`](#device-sizes) to reduce the total number of possible generated images.
|
||||
You can configure [`deviceSizes`](#device-sizes) and [`imageSizes`](#device-sizes) to reduce the total number of possible generated images.
|
||||
|
||||
## Related
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ Make sure your `images` field follows the allowed config shape and values:
|
|||
module.exports = {
|
||||
images: {
|
||||
// limit of 25 deviceSizes values
|
||||
deviceSizes: [320, 420, 768, 1024, 1200],
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
||||
// limit of 25 imageSizes values
|
||||
imageSizes: [],
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
// limit of 50 domains values
|
||||
domains: [],
|
||||
path: '/_next/image',
|
||||
|
|
|
@ -63,8 +63,9 @@ const {
|
|||
domains: configDomains,
|
||||
} = imageData
|
||||
// sort smallest to largest
|
||||
const allSizes = [...configDeviceSizes, ...configImageSizes]
|
||||
configDeviceSizes.sort((a, b) => a - b)
|
||||
configImageSizes.sort((a, b) => a - b)
|
||||
allSizes.sort((a, b) => a - b)
|
||||
|
||||
let cachedObserver: IntersectionObserver
|
||||
|
||||
|
@ -105,28 +106,26 @@ function unLazifyImage(lazyImage: HTMLImageElement): void {
|
|||
lazyImage.classList.remove('__lazy')
|
||||
}
|
||||
|
||||
function getDeviceSizes(
|
||||
function getSizes(
|
||||
width: number | undefined,
|
||||
layout: LayoutValue
|
||||
): number[] {
|
||||
): { sizes: number[]; kind: 'w' | 'x' } {
|
||||
if (
|
||||
typeof width !== 'number' ||
|
||||
layout === 'fill' ||
|
||||
layout === 'responsive'
|
||||
) {
|
||||
return configDeviceSizes
|
||||
return { sizes: configDeviceSizes, kind: 'w' }
|
||||
}
|
||||
if (configImageSizes.includes(width)) {
|
||||
return [width]
|
||||
}
|
||||
const widths: number[] = []
|
||||
for (let size of configDeviceSizes) {
|
||||
widths.push(size)
|
||||
if (size >= width) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return widths
|
||||
|
||||
const sizes = [
|
||||
...new Set(
|
||||
[width, width * 2, width * 3].map(
|
||||
(w) => allSizes.find((p) => p >= w) || allSizes[allSizes.length - 1]
|
||||
)
|
||||
),
|
||||
]
|
||||
return { sizes, kind: 'x' }
|
||||
}
|
||||
|
||||
function computeSrc(
|
||||
|
@ -139,8 +138,8 @@ function computeSrc(
|
|||
if (unoptimized) {
|
||||
return src
|
||||
}
|
||||
const widths = getDeviceSizes(width, layout)
|
||||
const largest = widths[widths.length - 1]
|
||||
const { sizes } = getSizes(width, layout)
|
||||
const largest = sizes[sizes.length - 1]
|
||||
return callLoader({ src, width: largest, quality })
|
||||
}
|
||||
|
||||
|
@ -176,8 +175,14 @@ function generateSrcSet({
|
|||
return undefined
|
||||
}
|
||||
|
||||
return getDeviceSizes(width, layout)
|
||||
.map((w) => `${callLoader({ src, width: w, quality })} ${w}w`)
|
||||
const { sizes, kind } = getSizes(width, layout)
|
||||
return sizes
|
||||
.map(
|
||||
(size, i) =>
|
||||
`${callLoader({ src, width: size, quality })} ${
|
||||
kind === 'w' ? size : i + 1
|
||||
}${kind}`
|
||||
)
|
||||
.join(', ')
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ const defaultConfig: { [key: string]: any } = {
|
|||
compress: true,
|
||||
analyticsId: process.env.VERCEL_ANALYTICS_ID || '',
|
||||
images: {
|
||||
deviceSizes: [320, 420, 768, 1024, 1200],
|
||||
imageSizes: [],
|
||||
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
|
||||
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
|
||||
domains: [],
|
||||
path: '/_next/image',
|
||||
loader: 'default',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module.exports = {
|
||||
images: {
|
||||
deviceSizes: [480, 1024, 1600, 2000],
|
||||
imageSizes: [16, 64],
|
||||
imageSizes: [16, 32, 48, 64],
|
||||
path: 'https://example.com/myaccount/',
|
||||
loader: 'imgix',
|
||||
},
|
||||
|
|
|
@ -54,11 +54,11 @@ const ClientSide = () => {
|
|||
height={400}
|
||||
/>
|
||||
<Image
|
||||
id="icon-image-64"
|
||||
id="icon-image-32"
|
||||
src="/icon.png"
|
||||
loading="eager"
|
||||
width={64}
|
||||
height={64}
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<Image
|
||||
id="icon-image-16"
|
||||
|
|
|
@ -71,11 +71,11 @@ const Page = () => {
|
|||
height={400}
|
||||
/>
|
||||
<Image
|
||||
id="icon-image-64"
|
||||
id="icon-image-32"
|
||||
src="/icon.png"
|
||||
loading="eager"
|
||||
width={64}
|
||||
height={64}
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<Image
|
||||
id="icon-image-16"
|
||||
|
|
|
@ -33,46 +33,46 @@ function runTests() {
|
|||
})
|
||||
it('should modify src with the loader', async () => {
|
||||
expect(await browser.elementById('basic-image').getAttribute('src')).toBe(
|
||||
'https://example.com/myaccount/foo.jpg?auto=format&fit=max&w=480&q=60'
|
||||
'https://example.com/myaccount/foo.jpg?auto=format&fit=max&w=1024&q=60'
|
||||
)
|
||||
})
|
||||
it('should correctly generate src even if preceding slash is included in prop', async () => {
|
||||
expect(
|
||||
await browser.elementById('preceding-slash-image').getAttribute('src')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/fooslash.jpg?auto=format&fit=max&w=480'
|
||||
'https://example.com/myaccount/fooslash.jpg?auto=format&fit=max&w=1024'
|
||||
)
|
||||
})
|
||||
it('should add a srcset based on the loader', async () => {
|
||||
expect(
|
||||
await browser.elementById('basic-image').getAttribute('srcset')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/foo.jpg?auto=format&fit=max&w=480&q=60 480w'
|
||||
'https://example.com/myaccount/foo.jpg?auto=format&fit=max&w=480&q=60 1x, https://example.com/myaccount/foo.jpg?auto=format&fit=max&w=1024&q=60 2x'
|
||||
)
|
||||
})
|
||||
it('should add a srcset even with preceding slash in prop', async () => {
|
||||
expect(
|
||||
await browser.elementById('preceding-slash-image').getAttribute('srcset')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/fooslash.jpg?auto=format&fit=max&w=480 480w'
|
||||
'https://example.com/myaccount/fooslash.jpg?auto=format&fit=max&w=480 1x, https://example.com/myaccount/fooslash.jpg?auto=format&fit=max&w=1024 2x'
|
||||
)
|
||||
})
|
||||
it('should use imageSizes when width matches, not deviceSizes from next.config.js', async () => {
|
||||
expect(await browser.elementById('icon-image-16').getAttribute('src')).toBe(
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=16'
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=48'
|
||||
)
|
||||
expect(
|
||||
await browser.elementById('icon-image-16').getAttribute('srcset')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=16 16w'
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=16 1x, https://example.com/myaccount/icon.png?auto=format&fit=max&w=32 2x, https://example.com/myaccount/icon.png?auto=format&fit=max&w=48 3x'
|
||||
)
|
||||
expect(await browser.elementById('icon-image-64').getAttribute('src')).toBe(
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=64'
|
||||
expect(await browser.elementById('icon-image-32').getAttribute('src')).toBe(
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=480'
|
||||
)
|
||||
expect(
|
||||
await browser.elementById('icon-image-64').getAttribute('srcset')
|
||||
await browser.elementById('icon-image-32').getAttribute('srcset')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=64 64w'
|
||||
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=32 1x, https://example.com/myaccount/icon.png?auto=format&fit=max&w=64 2x, https://example.com/myaccount/icon.png?auto=format&fit=max&w=480 3x'
|
||||
)
|
||||
})
|
||||
it('should support the unoptimized attribute', async () => {
|
||||
|
@ -90,10 +90,10 @@ function runTests() {
|
|||
function lazyLoadingTests() {
|
||||
it('should have loaded the first image immediately', async () => {
|
||||
expect(await browser.elementById('lazy-top').getAttribute('src')).toBe(
|
||||
'https://example.com/myaccount/foo1.jpg?auto=format&fit=max&w=1024'
|
||||
'https://example.com/myaccount/foo1.jpg?auto=format&fit=max&w=2000'
|
||||
)
|
||||
expect(await browser.elementById('lazy-top').getAttribute('srcset')).toBe(
|
||||
'https://example.com/myaccount/foo1.jpg?auto=format&fit=max&w=480 480w, https://example.com/myaccount/foo1.jpg?auto=format&fit=max&w=1024 1024w'
|
||||
'https://example.com/myaccount/foo1.jpg?auto=format&fit=max&w=1024 1x, https://example.com/myaccount/foo1.jpg?auto=format&fit=max&w=2000 2x'
|
||||
)
|
||||
})
|
||||
it('should not have loaded the second image immediately', async () => {
|
||||
|
@ -121,11 +121,11 @@ function lazyLoadingTests() {
|
|||
|
||||
await check(() => {
|
||||
return browser.elementById('lazy-mid').getAttribute('src')
|
||||
}, 'https://example.com/myaccount/foo2.jpg?auto=format&fit=max&w=480')
|
||||
}, 'https://example.com/myaccount/foo2.jpg?auto=format&fit=max&w=1024')
|
||||
|
||||
await check(() => {
|
||||
return browser.elementById('lazy-mid').getAttribute('srcset')
|
||||
}, 'https://example.com/myaccount/foo2.jpg?auto=format&fit=max&w=480 480w')
|
||||
}, 'https://example.com/myaccount/foo2.jpg?auto=format&fit=max&w=480 1x, https://example.com/myaccount/foo2.jpg?auto=format&fit=max&w=1024 2x')
|
||||
})
|
||||
it('should not have loaded the third image after scrolling down', async () => {
|
||||
expect(
|
||||
|
@ -170,11 +170,11 @@ function lazyLoadingTests() {
|
|||
await waitFor(200)
|
||||
expect(
|
||||
await browser.elementById('lazy-without-attribute').getAttribute('src')
|
||||
).toBe('https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=1024')
|
||||
).toBe('https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=2000')
|
||||
expect(
|
||||
await browser.elementById('lazy-without-attribute').getAttribute('srcset')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=480 480w, https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=1024 1024w'
|
||||
'https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=1024 1x, https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=1600 2x, https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=2000 3x'
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -220,14 +220,14 @@ describe('Image Component Tests', () => {
|
|||
it('should add a preload tag for a priority image', async () => {
|
||||
expect(
|
||||
await hasPreloadLinkMatchingUrl(
|
||||
'https://example.com/myaccount/withpriority.png?auto=format&fit=max&w=480&q=60'
|
||||
'https://example.com/myaccount/withpriority.png?auto=format&fit=max&w=1024&q=60'
|
||||
)
|
||||
).toBe(true)
|
||||
})
|
||||
it('should add a preload tag for a priority image with preceding slash', async () => {
|
||||
expect(
|
||||
await hasPreloadLinkMatchingUrl(
|
||||
'https://example.com/myaccount/fooslash.jpg?auto=format&fit=max&w=480'
|
||||
'https://example.com/myaccount/fooslash.jpg?auto=format&fit=max&w=1024'
|
||||
)
|
||||
).toBe(true)
|
||||
})
|
||||
|
@ -241,7 +241,7 @@ describe('Image Component Tests', () => {
|
|||
it('should add a preload tag for a priority image, with quality', async () => {
|
||||
expect(
|
||||
await hasPreloadLinkMatchingUrl(
|
||||
'https://example.com/myaccount/withpriority.png?auto=format&fit=max&w=480&q=60'
|
||||
'https://example.com/myaccount/withpriority.png?auto=format&fit=max&w=1024&q=60'
|
||||
)
|
||||
).toBe(true)
|
||||
})
|
||||
|
@ -295,12 +295,12 @@ describe('Image Component Tests', () => {
|
|||
expect(
|
||||
await browser.elementById('lazy-no-observer').getAttribute('src')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=1024'
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=2000'
|
||||
)
|
||||
expect(
|
||||
await browser.elementById('lazy-no-observer').getAttribute('srcset')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=480 480w, https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=1024 1024w'
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=1024 1x, https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=2000 2x'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
@ -321,12 +321,12 @@ describe('Image Component Tests', () => {
|
|||
expect(
|
||||
await browser.elementById('lazy-no-observer').getAttribute('src')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=1024'
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=2000'
|
||||
)
|
||||
expect(
|
||||
await browser.elementById('lazy-no-observer').getAttribute('srcset')
|
||||
).toBe(
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=480 480w, https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=1024 1024w'
|
||||
'https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=1024 1x, https://example.com/myaccount/foox.jpg?auto=format&fit=max&w=2000 2x'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -80,7 +80,7 @@ function runTests(mode) {
|
|||
expect(
|
||||
await hasImageMatchingUrl(
|
||||
browser,
|
||||
`http://localhost:${appPort}/_next/image?url=%2Ftest.jpg&w=420&q=75`
|
||||
`http://localhost:${appPort}/_next/image?url=%2Ftest.jpg&w=1200&q=75`
|
||||
)
|
||||
).toBe(true)
|
||||
} finally {
|
||||
|
@ -120,10 +120,10 @@ function runTests(mode) {
|
|||
const delta = 250
|
||||
const id = 'fixed1'
|
||||
expect(await getSrc(browser, id)).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=1200&q=75'
|
||||
'/_next/image?url=%2Fwide.png&w=3840&q=75'
|
||||
)
|
||||
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=320&q=75 320w, /_next/image?url=%2Fwide.png&w=420&q=75 420w, /_next/image?url=%2Fwide.png&w=768&q=75 768w, /_next/image?url=%2Fwide.png&w=1024&q=75 1024w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w'
|
||||
'/_next/image?url=%2Fwide.png&w=1200&q=75 1x, /_next/image?url=%2Fwide.png&w=3840&q=75 2x'
|
||||
)
|
||||
await browser.setDimensions({
|
||||
width: width + delta,
|
||||
|
@ -153,10 +153,10 @@ function runTests(mode) {
|
|||
const delta = 250
|
||||
const id = 'intrinsic1'
|
||||
expect(await getSrc(browser, id)).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=1200&q=75'
|
||||
'/_next/image?url=%2Fwide.png&w=3840&q=75'
|
||||
)
|
||||
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=320&q=75 320w, /_next/image?url=%2Fwide.png&w=420&q=75 420w, /_next/image?url=%2Fwide.png&w=768&q=75 768w, /_next/image?url=%2Fwide.png&w=1024&q=75 1024w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w'
|
||||
'/_next/image?url=%2Fwide.png&w=1200&q=75 1x, /_next/image?url=%2Fwide.png&w=3840&q=75 2x'
|
||||
)
|
||||
await browser.setDimensions({
|
||||
width: width + delta,
|
||||
|
@ -189,10 +189,10 @@ function runTests(mode) {
|
|||
const delta = 250
|
||||
const id = 'responsive1'
|
||||
expect(await getSrc(browser, id)).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=1200&q=75'
|
||||
'/_next/image?url=%2Fwide.png&w=3840&q=75'
|
||||
)
|
||||
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=320&q=75 320w, /_next/image?url=%2Fwide.png&w=420&q=75 420w, /_next/image?url=%2Fwide.png&w=768&q=75 768w, /_next/image?url=%2Fwide.png&w=1024&q=75 1024w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w'
|
||||
'/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w'
|
||||
)
|
||||
await browser.setDimensions({
|
||||
width: width + delta,
|
||||
|
@ -225,10 +225,10 @@ function runTests(mode) {
|
|||
const delta = 150
|
||||
const id = 'fill1'
|
||||
expect(await getSrc(browser, id)).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=1200&q=75'
|
||||
'/_next/image?url=%2Fwide.png&w=3840&q=75'
|
||||
)
|
||||
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=320&q=75 320w, /_next/image?url=%2Fwide.png&w=420&q=75 420w, /_next/image?url=%2Fwide.png&w=768&q=75 768w, /_next/image?url=%2Fwide.png&w=1024&q=75 1024w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w'
|
||||
'/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w'
|
||||
)
|
||||
await browser.setDimensions({
|
||||
width: width + delta,
|
||||
|
@ -261,10 +261,10 @@ function runTests(mode) {
|
|||
const height = await getComputed(browser, id, 'height')
|
||||
await browser.eval(`document.getElementById("${id}").scrollIntoView()`)
|
||||
expect(await getSrc(browser, id)).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=1200&q=75'
|
||||
'/_next/image?url=%2Fwide.png&w=3840&q=75'
|
||||
)
|
||||
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
|
||||
'/_next/image?url=%2Fwide.png&w=320&q=75 320w, /_next/image?url=%2Fwide.png&w=420&q=75 420w, /_next/image?url=%2Fwide.png&w=768&q=75 768w, /_next/image?url=%2Fwide.png&w=1024&q=75 1024w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w'
|
||||
'/_next/image?url=%2Fwide.png&w=640&q=75 640w, /_next/image?url=%2Fwide.png&w=750&q=75 750w, /_next/image?url=%2Fwide.png&w=828&q=75 828w, /_next/image?url=%2Fwide.png&w=1080&q=75 1080w, /_next/image?url=%2Fwide.png&w=1200&q=75 1200w, /_next/image?url=%2Fwide.png&w=1920&q=75 1920w, /_next/image?url=%2Fwide.png&w=2048&q=75 2048w, /_next/image?url=%2Fwide.png&w=3840&q=75 3840w'
|
||||
)
|
||||
expect(await getComputed(browser, id, 'width')).toBe(width)
|
||||
expect(await getComputed(browser, id, 'height')).toBe(height)
|
||||
|
|
|
@ -19,7 +19,7 @@ jest.setTimeout(1000 * 60 * 2)
|
|||
const appDir = join(__dirname, '../')
|
||||
const imagesDir = join(appDir, '.next', 'cache', 'images')
|
||||
const nextConfig = new File(join(appDir, 'next.config.js'))
|
||||
const largeSize = 1024
|
||||
const largeSize = 1080 // defaults defined in server/config.ts
|
||||
let appPort
|
||||
let app
|
||||
|
||||
|
@ -441,7 +441,7 @@ describe('Image Optimizer', () => {
|
|||
const domains = ['localhost', 'example.com']
|
||||
|
||||
describe('dev support w/o next.config.js', () => {
|
||||
const size = 320 // defaults defined in server/config.ts
|
||||
const size = 384 // defaults defined in server/config.ts
|
||||
beforeAll(async () => {
|
||||
appPort = await findPort()
|
||||
app = await launchApp(appDir, appPort)
|
||||
|
@ -478,7 +478,7 @@ describe('Image Optimizer', () => {
|
|||
})
|
||||
|
||||
describe('Server support w/o next.config.js', () => {
|
||||
const size = 320 // defaults defined in server/config.ts
|
||||
const size = 384 // defaults defined in server/config.ts
|
||||
beforeAll(async () => {
|
||||
await nextBuild(appDir)
|
||||
appPort = await findPort()
|
||||
|
@ -557,7 +557,8 @@ describe('Image Optimizer', () => {
|
|||
await fs.remove(imagesDir)
|
||||
})
|
||||
it('should 404 when loader is not default', async () => {
|
||||
const query = { w: 320, q: 90, url: '/test.svg' }
|
||||
const size = 384 // defaults defined in server/config.ts
|
||||
const query = { w: size, q: 90, url: '/test.svg' }
|
||||
const opts = { headers: { accept: 'image/webp' } }
|
||||
const res = await fetchViaHTTP(appPort, '/_next/image', query, opts)
|
||||
expect(res.status).toBe(404)
|
||||
|
|
Loading…
Reference in a new issue