Skip to content

Commit

Permalink
Merge 2ec1277 into 153a4a2
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce committed Oct 6, 2020
2 parents 153a4a2 + 2ec1277 commit c91d2ed
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 9 deletions.
39 changes: 34 additions & 5 deletions lighthouse-core/audits/image-size-responsive.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ function allowedImageSize(displayedWidth, displayedHeight, DPR) {
* @return {[number, number]}
*/
function expectedImageSize(displayedWidth, displayedHeight, DPR) {
const width = Math.ceil(DPR * displayedWidth);
const height = Math.ceil(DPR * displayedHeight);
const width = Math.ceil(quantizeDpr(DPR) * displayedWidth);
const height = Math.ceil(quantizeDpr(DPR) * displayedHeight);
return [width, height];
}

Expand Down Expand Up @@ -241,15 +241,44 @@ class ImageSizeResponsive extends Audit {
/**
* Return a quantized version of the DPR.
*
* This is to relax the required size of the image, as there are some densities that are not that
* common, and the default DPR used in some contexts by lightouse is 2.625.
* This is to relax the required size of the image.
* There's strong evidence that 3 DPR images are not perceived to be significantly better to mobile users than
* 2 DPR images. The additional high byte cost (3x images are ~225% the file size of 2x images) makes this practice
* difficult to recommend.
*
* Human minimum visual acuity angle = 0.016 degrees (see Sun Microsystems paper)
* Typical phone operating distance from eye = 12 in
*
* A
* _
* \ | B
* \|
* θ
* A = minimum observable pixel size = ?
* B = viewing distance = 12 in
* θ = human minimum visual acuity angle = 0.016 degrees
*
* tan θ = A / B ---- Solve for A
* A = tan (0.016 degrees) * B = 0.00335 in
*
* Moto G4 display width = 2.7 in
* Moto G4 horizontal 2x resolution = 720 pixels
* Moto G4 horizontal 3x resolution = 1080 pixels
*
* Moto G4 1x pixel size = 2.7 / 360 = 0.0075 in
* Moto G4 2x pixel size = 2.7 / 720 = 0.00375 in
* Moto G4 3x pixel size = 2.7 / 1080 = 0.0025 in
*
* Wasted additional pixels in 3x image = (.00335 - .0025) / (.00375 - .0025) = 68% waste
*
*
* @see https://www.swift.ac.uk/about/files/vision.pdf
* @param {number} dpr
* @return {number}
*/
function quantizeDpr(dpr) {
if (dpr >= 2) {
return Math.floor(dpr);
return 2;
}
if (dpr >= 1.5) {
return 1.5;
Expand Down
19 changes: 17 additions & 2 deletions lighthouse-core/test/audits/image-size-responsive-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,20 @@ describe('Images: size audit', () => {
});
});

describe('DPR = 2.625', () => {
describe('DPR = higher than 2', () => {
testImage('is an icon with right size', {
score: 1,
clientSize: [64, 64],
naturalSize: [128, 128],
devicePixelRatio: 2.625,

});

testImage('is an icon with right size', {
score: 1,
clientSize: [64, 64],
naturalSize: [128, 128],
devicePixelRatio: 3,
});

testImage('is an icon with an invalid size', {
Expand All @@ -341,6 +349,13 @@ describe('Images: size audit', () => {
devicePixelRatio: 2.625,
});

testImage('has right size', {
score: 1,
clientSize: [65, 65],
naturalSize: [98, 98],
devicePixelRatio: 3,
});

testImage('has an invalid size', {
score: 0,
clientSize: [65, 65],
Expand Down Expand Up @@ -424,6 +439,6 @@ describe('Images: size audit', () => {
},
});
assert.equal(result.details.items.length, 1);
assert.equal(result.details.items[0].expectedSize, '217 x 109');
assert.equal(result.details.items[0].expectedSize, '160 x 80');
});
});
4 changes: 2 additions & 2 deletions lighthouse-core/test/results/sample_v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,8 @@
"displayedSize": "480 x 318",
"actualSize": "480 x 318",
"actualPixels": 152640,
"expectedSize": "1260 x 835",
"expectedPixels": 1052100
"expectedSize": "960 x 636",
"expectedPixels": 610560
}
]
}
Expand Down

0 comments on commit c91d2ed

Please sign in to comment.