From 8a0ae280cdd648a861f07d43affba7ebd18bc62c Mon Sep 17 00:00:00 2001 From: Sebastian Kreft Date: Thu, 19 Mar 2020 12:41:59 -0300 Subject: [PATCH 1/3] feature: add usesPixelArtScaling flag to images This new flag will be used by the ImageSizeResponsive audit (#10245), as those images are intendedly displayed in a pixelated form, so the audit should not flag them. Note that `image-rendering: -mo-crisp-edges;` is also an accepted value in Firefox, however in such case, the computed style will return `crips-edges`. --- lighthouse-core/gather/gatherers/image-elements.js | 12 ++++++++++++ types/artifacts.d.ts | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/lighthouse-core/gather/gatherers/image-elements.js b/lighthouse-core/gather/gatherers/image-elements.js index 7d26883e0774..0741b2a3d6ae 100644 --- a/lighthouse-core/gather/gatherers/image-elements.js +++ b/lighthouse-core/gather/gatherers/image-elements.js @@ -29,6 +29,16 @@ function getClientRect(element) { }; } +/** + * @param {CSSStyleDeclaration} style + * @return {boolean} + */ +function usesPixelArtScaling(style) { + return ['pixelated', 'crisp-edges'].includes( + style.getPropertyValue('image-rendering') + ); +} + /** * @param {Array} allElements * @return {Array} @@ -58,6 +68,7 @@ function getHTMLImages(allElements) { usesObjectFit: ['cover', 'contain', 'scale-down', 'none'].includes( computedStyle.getPropertyValue('object-fit') ), + usesPixelArtScaling: usesPixelArtScaling(computedStyle), }; }); } @@ -95,6 +106,7 @@ function getCSSImages(allElements) { isCss: true, isPicture: false, usesObjectFit: false, + usesPixelArtScaling: usesPixelArtScaling(style), resourceSize: 0, // this will get overwritten below }); } diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts index a5ca7517f793..25dddb58157f 100644 --- a/types/artifacts.d.ts +++ b/types/artifacts.d.ts @@ -394,6 +394,11 @@ declare global { isPicture: boolean; /** Flags whether this element was sized using a non-default `object-fit` CSS property. */ usesObjectFit: boolean; + /** Flags whether this element was rendered using a pixel art scaling method. + * See https://developer.mozilla.org/en-US/docs/Games/Techniques/Crisp_pixel_art_look for + * details. + */ + usesPixelArtScaling: boolean; /** The size of the underlying image file in bytes. 0 if the file could not be identified. */ resourceSize: number; /** The MIME type of the underlying image file. */ From 186a337d322971e6fd137658f034f34023fcf1bf Mon Sep 17 00:00:00 2001 From: Sebastian Kreft Date: Thu, 19 Mar 2020 14:08:47 -0300 Subject: [PATCH 2/3] Fix how usesPixelArtRendering is computed Apparently the code is executed in another process, which means, that functions mus be inlined, otherwise the code needs to go through some extra hoops. --- .../gather/gatherers/image-elements.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/lighthouse-core/gather/gatherers/image-elements.js b/lighthouse-core/gather/gatherers/image-elements.js index 0741b2a3d6ae..4cd654f875e6 100644 --- a/lighthouse-core/gather/gatherers/image-elements.js +++ b/lighthouse-core/gather/gatherers/image-elements.js @@ -29,15 +29,7 @@ function getClientRect(element) { }; } -/** - * @param {CSSStyleDeclaration} style - * @return {boolean} - */ -function usesPixelArtScaling(style) { - return ['pixelated', 'crisp-edges'].includes( - style.getPropertyValue('image-rendering') - ); -} +const PIXEL_ART_RENDERING = ['pixelated', 'crisp-edges']; /** * @param {Array} allElements @@ -68,7 +60,9 @@ function getHTMLImages(allElements) { usesObjectFit: ['cover', 'contain', 'scale-down', 'none'].includes( computedStyle.getPropertyValue('object-fit') ), - usesPixelArtScaling: usesPixelArtScaling(computedStyle), + usesPixelArtScaling: ['pixelated', 'crisp-edges'].includes( + computedStyle.getPropertyValue('image-rendering') + ), }; }); } @@ -106,7 +100,9 @@ function getCSSImages(allElements) { isCss: true, isPicture: false, usesObjectFit: false, - usesPixelArtScaling: usesPixelArtScaling(style), + usesPixelArtScaling: ['pixelated', 'crisp-edges'].includes( + style.getPropertyValue('image-rendering') + ), resourceSize: 0, // this will get overwritten below }); } From be9207819986c3a27f3206baf9b7e35f6fce2784 Mon Sep 17 00:00:00 2001 From: Sebastian Kreft Date: Thu, 19 Mar 2020 14:24:36 -0300 Subject: [PATCH 3/3] Add usesSrcSetDensityDescriptor --- lighthouse-core/gather/gatherers/image-elements.js | 5 +++-- types/artifacts.d.ts | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lighthouse-core/gather/gatherers/image-elements.js b/lighthouse-core/gather/gatherers/image-elements.js index 4cd654f875e6..dc2a1654a169 100644 --- a/lighthouse-core/gather/gatherers/image-elements.js +++ b/lighthouse-core/gather/gatherers/image-elements.js @@ -29,8 +29,6 @@ function getClientRect(element) { }; } -const PIXEL_ART_RENDERING = ['pixelated', 'crisp-edges']; - /** * @param {Array} allElements * @return {Array} @@ -63,6 +61,8 @@ function getHTMLImages(allElements) { usesPixelArtScaling: ['pixelated', 'crisp-edges'].includes( computedStyle.getPropertyValue('image-rendering') ), + // https://html.spec.whatwg.org/multipage/images.html#pixel-density-descriptor + usesSrcSetDensityDescriptor: / \d+(\.\d+)?x/.test(element.srcset), }; }); } @@ -103,6 +103,7 @@ function getCSSImages(allElements) { usesPixelArtScaling: ['pixelated', 'crisp-edges'].includes( style.getPropertyValue('image-rendering') ), + usesSrcSetDensityDescriptor: false, resourceSize: 0, // this will get overwritten below }); } diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts index 25dddb58157f..9663b5c398f9 100644 --- a/types/artifacts.d.ts +++ b/types/artifacts.d.ts @@ -399,6 +399,10 @@ declare global { * details. */ usesPixelArtScaling: boolean; + /** Flags whether the image has a srcset with density descriptors. + * See https://html.spec.whatwg.org/multipage/images.html#pixel-density-descriptor + */ + usesSrcSetDensityDescriptor: boolean; /** The size of the underlying image file in bytes. 0 if the file could not be identified. */ resourceSize: number; /** The MIME type of the underlying image file. */