Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential LCP Reporting Issue on mobile for <image> #16245

Closed
3 tasks done
SteGreig opened this issue Nov 8, 2024 · 2 comments
Closed
3 tasks done

Potential LCP Reporting Issue on mobile for <image> #16245

SteGreig opened this issue Nov 8, 2024 · 2 comments
Assignees

Comments

@SteGreig
Copy link

SteGreig commented Nov 8, 2024

FAQ

URL

https://hfs.staging2.adtrak.agency/

What happened?

I have an SVG <image> element - the href value is a small (480x370) image for mobile

The larger image URL is stored in a data attribute on that image element

<svg role="img" viewBox="0 0 1025 800" fill="none" xmlns="http://www.w3.org/2000/svg">
          <defs>
            <clipPath id="heroimg" clipPathUnits="userSpaceOnUse">
              <path d="..." fill="black"/>
            </clipPath>
          </defs>
          <image
            fetchpriority="high"
            width="100%"
            height="100%"
            preserveAspectRatio="xMinYMin slice"
            href="{{image_url|resize(480,370)|towebp}}"
            data-src-small="{{image_url|resize(480,370)|towebp}}"
            data-src-large="{{image_url|resize(1300,1000)|towebp}}"
            clip-path="url(#heroimg)"
            class="svg-responsive-image"
          />
</svg>

I'm then using JS to change the href value based on the screen size (<768 should get the smaller image, wider screens the larger image).

function updateSVGImage() {
  const imageEls = document.querySelectorAll('.svg-responsive-image');
  const screenWidth = window.innerWidth;

  imageEls?.forEach((image) => {

    // Adjust image source based on screen size
    if (screenWidth < 768) {
      image.setAttribute('href', image.getAttribute('data-src-small'));
    } else {
      image.setAttribute('href', image.getAttribute('data-src-large'));
    }

  })
}

// Run on page load and when resizing
window.addEventListener('load', updateSVGImage);
window.addEventListener('resize', updateSVGImage);

The code all works correctly and does what it should. However, the mobile Lighthouse report shows a very high LCP time, and shows that the href is the larger image url, and reports that I should preload my LCP image (I am preloading the mobile version, not the larger version).

I have verified that the code is working correctly - the Network tab shows that the larger image is not downloaded at all unless the browser is wider than 768px.

From my testing, the threshold seems to be 1040px. To clarify:

if (screenWidth < 1041) results in the smaller image being used in the mobile Lighthouse report

if (screenWidth < 1040) results in the larger image being used in the mobile Lighthouse report

What did you expect?

I would expect the threshold for mobile/desktop in Lighthouse to be much smaller in these lab results, considering the screenshots displayed, and the fact it says the test uses a Moto G Power device.

I also don't recall having this problem when using the <picture> element to deliver different image sources at different viewport widths.

What have you tried?

My testing showed that the issue is based on the viewport size. I can confirm the following behaviour:

If I use JS to update the href to the larger image URL when the viewport is 1040px or more, Lighthouse uses this larger image url in the mobile report.

If I use JS to update the href to the larger image URL when the viewport is 1041px or more, Lighthouse uses the smaller image url in the mobile report.

How were you running Lighthouse?

PageSpeed Insights, Chrome DevTools

Lighthouse Version

12.2.1

Chrome Version

No response

Node Version

No response

OS

Mac

Relevant log output

No response

@adamraine
Copy link
Member

window.innerWidth can be larger than the Moto G Power viewport width if the page's layout size is larger than 412px. If I simulate a mobile device with DevTools the entire page is horizontally scrollable, which explains why window.innerWidth is larger than the device viewport in your case:

Screenshot 2024-11-08 at 11 28 09 AM

window.outerWidth should give you a value of 412 when Lighthouse emulates a Moto G Power, but I imagine this horizontal scroll behavior is a bug too.

@adamraine adamraine closed this as not planned Won't fix, can't repro, duplicate, stale Nov 8, 2024
@SteGreig
Copy link
Author

SteGreig commented Nov 9, 2024

Thank you, I thought there must be a logical explanation!

Hadn't caught the horizontal scroll bug as it doesn't occur on devices I've tested on. Was being caused by a not-yet-loaded image further down the page which was taking the size of its 1024 width attribute value - seems it's immediate parent needs width 100% for the max-width:100% to work on the image before its loaded.

Sorry for the time waste!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants