Skip to content

Commit

Permalink
feat(next/image): reduce byte waste for 3x screens (#20610)
Browse files Browse the repository at this point in the history
https://blog.twitter.com/engineering/en_us/topics/infrastructure/2019/capping-image-fidelity-on-ultra-high-resolution-devices.html

> This means that most OLED screens that say they are 3x resolution, are actually 3x in the green color, but only 1.5x in the red and blue colors. Showing a 3x resolution image in the app vs a 2x resolution image will be visually the same, though the 3x image takes significantly more data. Even true 3x resolution screens are wasteful as the human eye cannot see that level of detail without something like a magnifying glass.

> ![image](https://user-images.githubusercontent.com/616428/103366340-61b61100-4a90-11eb-9c16-8467f8930247.png)

Even the iPhone doesn't have true 3x DPI!

related: #18756
  • Loading branch information
Timer authored Dec 30, 2020
1 parent c0ff5ef commit d1c5659
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 9 deletions.
10 changes: 9 additions & 1 deletion packages/next/client/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,15 @@ function getWidths(

const widths = [
...new Set(
[width, width * 2, width * 3].map(
// > This means that most OLED screens that say they are 3x resolution,
// > are actually 3x in the green color, but only 1.5x in the red and
// > blue colors. Showing a 3x resolution image in the app vs a 2x
// > resolution image will be visually the same, though the 3x image
// > takes significantly more data. Even true 3x resolution screens are
// > wasteful as the human eye cannot see that level of detail without
// > something like a magnifying glass.
// https://blog.twitter.com/engineering/en_us/topics/infrastructure/2019/capping-image-fidelity-on-ultra-high-resolution-devices.html
[width, width * 2 /*, width * 3*/].map(
(w) => allSizes.find((p) => p >= w) || allSizes[allSizes.length - 1]
)
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function runTests(mode) {
expect(
await hasImageMatchingUrl(
browser,
`http://localhost:${appPort}/docs/_next/image?url=%2Fdocs%2Ftest.jpg&w=1200&q=75`
`http://localhost:${appPort}/docs/_next/image?url=%2Fdocs%2Ftest.jpg&w=828&q=75`
)
).toBe(true)
} finally {
Expand Down
12 changes: 6 additions & 6 deletions test/integration/image-component/basic/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@ function runTests() {
})
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=48'
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=32'
)
expect(
await browser.elementById('icon-image-16').getAttribute('srcset')
).toBe(
'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'
'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'
)
expect(await browser.elementById('icon-image-32').getAttribute('src')).toBe(
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=480'
'https://example.com/myaccount/icon.png?auto=format&fit=max&w=64'
)
expect(
await browser.elementById('icon-image-32').getAttribute('srcset')
).toBe(
'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'
'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'
)
})
it('should support the unoptimized attribute', async () => {
Expand Down Expand Up @@ -172,11 +172,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=2000')
).toBe('https://example.com/myaccount/foo4.jpg?auto=format&fit=max&w=1600')
expect(
await browser.elementById('lazy-without-attribute').getAttribute('srcset')
).toBe(
'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'
'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'
)
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function runTests(mode) {
expect(
await hasImageMatchingUrl(
browser,
`http://localhost:${appPort}/_next/image?url=%2Ftest.jpg&w=1200&q=75`
`http://localhost:${appPort}/_next/image?url=%2Ftest.jpg&w=828&q=75`
)
).toBe(true)
} finally {
Expand Down

0 comments on commit d1c5659

Please sign in to comment.