diff --git a/core/audits/image-aspect-ratio.js b/core/audits/image-aspect-ratio.js index e0fe13070cd2..259dd5d40dcd 100644 --- a/core/audits/image-aspect-ratio.js +++ b/core/audits/image-aspect-ratio.js @@ -59,7 +59,16 @@ class ImageAspectRatio extends Audit { const displayedAspectRatio = image.displayedWidth / image.displayedHeight; const targetDisplayHeight = image.displayedWidth / actualAspectRatio; - const doRatiosMatch = Math.abs(targetDisplayHeight - image.displayedHeight) < THRESHOLD_PX; + const targetDisplayWidth = image.displayedHeight * actualAspectRatio; + + // Small rounding errors in aspect ratio can lead to large differences in target width/height + // if the aspect ratio is close to 0. + // + // In these cases, we should compare the smaller dimension because any rounding errors will + // affect that dimension less. + const doRatiosMatch = targetDisplayHeight < targetDisplayWidth + ? Math.abs(targetDisplayHeight - image.displayedHeight) < THRESHOLD_PX + : Math.abs(targetDisplayWidth - image.displayedWidth) < THRESHOLD_PX; return { url, diff --git a/core/test/audits/image-aspect-ratio-test.js b/core/test/audits/image-aspect-ratio-test.js index 8f548f9254e2..2657f04687e2 100644 --- a/core/test/audits/image-aspect-ratio-test.js +++ b/core/test/audits/image-aspect-ratio-test.js @@ -100,7 +100,7 @@ describe('Images: aspect-ratio audit', () => { }, }); - testImage('is almost the right aspect ratio', { + testImage('is almost the right expected height', { score: 1, clientSize: [412, 36], naturalSize: [800, 69], @@ -109,6 +109,15 @@ describe('Images: aspect-ratio audit', () => { }, }); + testImage('is a small aspect ratio with a rounding error', { + score: 1, + clientSize: [63, 256], + naturalSize: [32, 128], + props: { + isCss: false, + }, + }); + testImage('aspect ratios match', { score: 1, clientSize: [100, 100],