GoogleChrome / lighthouse

Automated auditing, performance metrics, and best practices for the web.
https://developer.chrome.com/docs/lighthouse/overview/
Apache License 2.0
28.34k stars 9.37k forks source link

Defer offscreen images includes a css file instead of only images #13338

Open tomasts248 opened 2 years ago

tomasts248 commented 2 years ago

FAQ

URL

https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fwww.otzerling.com%2F

What happened?

image

What did you expect?

To not consider a css file as an image.

What have you tried?

No response

How were you running Lighthouse?

PageSpeed Insights

Lighthouse Version

8.4.0

adamraine commented 2 years ago

I reproduced this on the 3rd try in PSI, but I haven't reproduced in Lighthouse.

adamraine commented 2 years ago

Lighthouse does find an image element with this CSS as it's source, but it doesn't appear in the offscreen-images audit:

{
  "src": "https://www.otzerling.com/wp-content/cache/autoptimize/css/autoptimize_a20027a7d5305a83fa1a09a234222d9a.css",
  "srcset": "",
  "displayedWidth": 0,
  "displayedHeight": 0,
  "clientRect": {
    "top": 0,
    "bottom": 0,
    "left": 0,
    "right": 0
  },
  "attributeWidth": null,
  "attributeHeight": null,
  "computedStyles": {
    "position": "static",
    "objectFit": "",
    "imageRendering": "auto"
  },
  "isCss": true,
  "isPicture": false,
  "isInShadowDOM": false,
  "node": {
    "lhId": "page-89-DIV",
    "devtoolsNodePath": "5,HTML,2,BODY,16,DIV,3,DIV,0,DIV,0,DIV,0,DIV,0,DIV,1,DIV,0,DIV",
    "selector": "div.brave_popupSections__wrap > div.brave_popupMargin__wrap > div.brave_popup__step__popup > div.brave_popup__step__content",
    "boundingRect": {
      "top": 0,
      "bottom": 0,
      "left": 0,
      "right": 0,
      "width": 0,
      "height": 0
    },
    "snippet": "<div class=\"brave_popup__step__content\">",
    "nodeLabel": " ¡Entérate de nuestras próximas actividades!Nombre*Correo*    Suscribete al Bol…"
  }
}
adamraine commented 2 years ago

Doing a

const el = document.querySelector('div.brave_popupSections__wrap > div.brave_popupMargin__wrap > div.brave_popup__step__popup > div.brave_popup__step__content');
window.getComputedStyle(el).backgroundImage;

in the console shows there is an element with this CSS file URL as it's background image source, so I think this is an issue with the page and Lighthouse is WAI.

tomasts248 commented 2 years ago

And confirmed you are correct it is the delayed popup image that causes the warning but why is it considered an inside css image? mmm image

adamraine commented 2 years ago

One of the outer divs has a background-image set to this CSS URL in the computed style:

Screen Shot 2021-11-08 at 3 41 44 PM

In the actual style:

Screen Shot 2021-11-08 at 3 45 02 PM

Looks like url() defaults to the stylesheet URL if its value is empty. Might be some way for Lighthouse to detect this.

brendankenny commented 2 years ago

Copying from #14286:

If an element has the style background: url(''), the url defaults to that of the main page itself (e.g. on https://example.com, that would be equivalent to background: url('https://example.com').

The ImageElements gatherer will then happily pick that up as an image, and then any audits that use that image will try to match it to a network record and succeed...because that's just the main document.

Here's one example report where it happens (check the option to defer the page itself as an offscreen image at __LIGHTHOUSE_JSON__.audits['offscreen-images'].details.items[2]).

brendankenny commented 2 years ago

I found this when working with preload-lcp-image. If the LCP element happened to have a background: url('') on it, ImageElements thinks it's an image even though it's not (the text itself is the LCP). The audit then tries to simulate a page load with the main document preloaded by the main document. The fact that this doesn't throw an error is the best thing you can say about this flow :)

paulirish commented 2 years ago

Plan is to

  1. pull in network requests to ImageElements gatherer, match up on URL (unfortunately but thats as good as we got)
  2. filter out items where resourceType != image
  3. maybe attach a requestId there, so in the audits we use that to match back up to the req. (just moving some of the matching logic closer to the gatherer so we don't have to do it in all our image audits)
  4. Probably new audit “image el does not have img network record”
connorjclark commented 2 years ago

Looks like devtools resource type isn't the magic bullet we hoped it was:

image

The type conveys the context the resource was requested under, not what blink actually thought of it.