Skip to content

Commit 600238f

Browse files
authored
breaking(next/image)!: remove 16px from default images.imageSizes config (#84647)
We took a look at unique Next.js projects that have one or more requests for a specific image size and here are the findings as seen from the Image Optimization API: - `w=16` 4.2% - `w=32` 17.1% - `w=48` 21.4% - `w=64` 22.6% - `w=96` 25.8% - `w=128` 29.5% - `w=256` 46.5% - `w=384` 35.1% - `w=640` 57.2% Only 4.2% of Next.js projects ever made a request to a 16px width image. This is low enough to remove from the default configuration so that all other projects can benefit from reduced html [srcset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset) and fewer variations exposed from the backend API. You might think that this means few developers are using `<Image width={16} />` but it probably means that most displays nowadays use devicePixelRatio 2 meaning that specifying a 16px image width will actually fetch the 32px width to ensure it won't looking blurry on your retina display. BREAKING CHANGE: this is technically a breaking change but it won't cause apps to stop working, its just 4% of them may have some requests serve a 32px image instead of 16px. Those apps can of course opt in by changing their `images.imageSizes` config back to allowing 16.
1 parent 79e7838 commit 600238f

File tree

15 files changed

+142
-28
lines changed

15 files changed

+142
-28
lines changed

crates/next-build-test/nextConfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"analyticsId": "",
2323
"images": {
2424
"deviceSizes": [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
25-
"imageSizes": [16, 32, 48, 64, 96, 128, 256, 384],
25+
"imageSizes": [32, 48, 64, 96, 128, 256, 384],
2626
"path": "/_next/image",
2727
"loader": "default",
2828
"loaderFile": "",

crates/next-core/src/next_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ impl Default for ImageConfig {
466466
// https://github.com/vercel/next.js/blob/327634eb/packages/next/shared/lib/image-config.ts#L100-L114
467467
Self {
468468
device_sizes: vec![640, 750, 828, 1080, 1200, 1920, 2048, 3840],
469-
image_sizes: vec![16, 32, 48, 64, 96, 128, 256, 384],
469+
image_sizes: vec![32, 48, 64, 96, 128, 256, 384],
470470
path: "/_next/image".to_string(),
471471
loader: ImageLoader::Default,
472472
loader_file: None,

docs/01-app/03-api-reference/02-components/image.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ If no configuration is provided, the default below is used:
684684
```js filename="next.config.js"
685685
module.exports = {
686686
images: {
687-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
687+
imageSizes: [32, 48, 64, 96, 128, 256, 384],
688688
},
689689
}
690690
```

docs/02-pages/04-api-reference/01-components/image-legacy.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ If no configuration is provided, the default below is used.
497497
```js filename="next.config.js"
498498
module.exports = {
499499
images: {
500-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
500+
imageSizes: [32, 48, 64, 96, 128, 256, 384],
501501
},
502502
}
503503
```

errors/invalid-images-config.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = {
1616
// limit of 25 deviceSizes values
1717
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
1818
// limit of 25 imageSizes values
19-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
19+
imageSizes: [32, 48, 64, 96, 128, 256, 384],
2020
// limit of 50 domains values (deprecated)
2121
domains: [],
2222
// path prefix for Image Optimization API, useful with `loader`

packages/next/src/shared/lib/image-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export type ImageConfig = Partial<ImageConfigComplete>
129129

130130
export const imageConfigDefault: ImageConfigComplete = {
131131
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
132-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
132+
imageSizes: [32, 48, 64, 96, 128, 256, 384],
133133
path: '/_next/image',
134134
loader: 'default',
135135
loaderFile: '',

test/integration/next-image-legacy/base-path/test/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ function runTests(mode) {
344344
return 'success'
345345
}, 'success')
346346
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
347-
'/docs/_next/image?url=%2Fdocs%2Fwide.png&w=16&q=75 16w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=32&q=75 32w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=48&q=75 48w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=64&q=75 64w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=96&q=75 96w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=128&q=75 128w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=256&q=75 256w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=384&q=75 384w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=640&q=75 640w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=750&q=75 750w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=828&q=75 828w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1080&q=75 1080w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1200&q=75 1200w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1920&q=75 1920w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=2048&q=75 2048w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=3840&q=75 3840w'
347+
'/docs/_next/image?url=%2Fdocs%2Fwide.png&w=32&q=75 32w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=48&q=75 48w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=64&q=75 64w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=96&q=75 96w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=128&q=75 128w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=256&q=75 256w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=384&q=75 384w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=640&q=75 640w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=750&q=75 750w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=828&q=75 828w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1080&q=75 1080w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1200&q=75 1200w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=1920&q=75 1920w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=2048&q=75 2048w, /docs/_next/image?url=%2Fdocs%2Fwide.png&w=3840&q=75 3840w'
348348
)
349349
expect(await browser.elementById(id).getAttribute('sizes')).toBe(
350350
'(max-width: 2048px) 1200px, 3840px'

test/integration/next-image-legacy/default/test/index.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ function runTests(mode) {
708708
return browser.eval(
709709
`document.querySelector('#fill4').getAttribute('srcset')`
710710
)
711-
}, '/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_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')
711+
}, '/_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_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')
712712
} finally {
713713
if (browser) {
714714
await browser.close()
@@ -732,7 +732,7 @@ function runTests(mode) {
732732
return 'success'
733733
}, 'success')
734734
expect(await browser.elementById(id).getAttribute('srcset')).toBe(
735-
'/_next/image?url=%2Fwide.png&w=16&q=75 16w, /_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_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'
735+
'/_next/image?url=%2Fwide.png&w=32&q=75 32w, /_next/image?url=%2Fwide.png&w=48&q=75 48w, /_next/image?url=%2Fwide.png&w=64&q=75 64w, /_next/image?url=%2Fwide.png&w=96&q=75 96w, /_next/image?url=%2Fwide.png&w=128&q=75 128w, /_next/image?url=%2Fwide.png&w=256&q=75 256w, /_next/image?url=%2Fwide.png&w=384&q=75 384w, /_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'
736736
)
737737
expect(await browser.elementById(id).getAttribute('sizes')).toBe(
738738
'(max-width: 2048px) 1200px, 3840px'

test/integration/next-image-new/app-dir-localpatterns/test/index.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function runTests(mode: 'dev' | 'server') {
8080
disableStaticImages: false,
8181
domains: [],
8282
formats: ['image/webp'],
83-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
83+
imageSizes: [32, 48, 64, 96, 128, 256, 384],
8484
loader: 'default',
8585
loaderFile: '',
8686
remotePatterns: [],
@@ -100,8 +100,8 @@ function runTests(mode: 'dev' | 'server') {
100100
path: '/_next/image',
101101
qualities: [75],
102102
sizes: [
103-
640, 750, 828, 1080, 1200, 1920, 2048, 3840, 16, 32, 48, 64, 96,
104-
128, 256, 384,
103+
640, 750, 828, 1080, 1200, 1920, 2048, 3840, 32, 48, 64, 96, 128,
104+
256, 384,
105105
],
106106
unoptimized: false,
107107
},

test/integration/next-image-new/app-dir-qualities/test/index.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function runTests(mode: 'dev' | 'server') {
9797
disableStaticImages: false,
9898
domains: [],
9999
formats: ['image/webp'],
100-
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
100+
imageSizes: [32, 48, 64, 96, 128, 256, 384],
101101
loader: 'default',
102102
loaderFile: '',
103103
remotePatterns: [],
@@ -106,8 +106,8 @@ function runTests(mode: 'dev' | 'server') {
106106
path: '/_next/image',
107107
qualities: [42, 69, 88],
108108
sizes: [
109-
640, 750, 828, 1080, 1200, 1920, 2048, 3840, 16, 32, 48, 64, 96,
110-
128, 256, 384,
109+
640, 750, 828, 1080, 1200, 1920, 2048, 3840, 32, 48, 64, 96, 128,
110+
256, 384,
111111
],
112112
unoptimized: false,
113113
},

0 commit comments

Comments
 (0)