Web-vitals extension reports INP because of delay in image requests

345 views
Skip to first unread message

Sander van Surksum

unread,
Nov 4, 2023, 12:46:12 PM11/4/23
to web-vitals-feedback
We encountered an INP issue on a PDP (Product Detail Page) of one of our client's websites. This particular product allows users to click on different color swatches to view the product in various shades.

Upon interaction, the issue arose as the 'img' element's 'src' attribute was dynamically updated with the URL of the selected color's image. This caused an unexpected delay in rendering the new image, because it has to fetch the new image before it can be displayed. From a user experience standpoint, it's clear why the INP metric was impacted—users were experiencing a noticeable delay before the new image appeared. But we haven't seen this issue before. 

To fix this, we found an easy solution: compressing the images. By reducing their file sizes, we speed up the image download process, effectively eliminating the delay. 

Has anyone else encountered a situation where your INP metrics were impacted due to delays in asset fetching?

I created a demo where you can see the issue. 

https://image-inp-test-djaz5ys0d-sandersu.vercel.app/

vs fixed

https://image-inp-test-8zclj36to-sandersu.vercel.app

Screenshot 2023-11-04 at 17.14.55.png

Michal Mocny

unread,
Nov 6, 2023, 2:04:27 PM11/6/23
to Sander van Surksum, web-vitals-feedback
Thank you for this example.  This is a great example where careful debugging is helpful.

What we have here is the following:
  • Interaction swaps in a new image src
  • The images are Huuuge! and take a long time to decode
  • Decoding is synchronous, so it blocks rendering.
  • INP does NOT measure network, but it does measure rendering delays.
  • If your image was not already loaded at all by the time of interaction, it won't block rendering and so wont affect INP.
Here is a screenshot of devtools tracing:
Screenshot 2023-11-06 at 13.59.56.png

Zoomed in closer on main thread:
Screenshot 2023-11-06 at 14.01.04.png

Notice that the click handler is very fast, and that INP measure the time to the very next screenshot with the new image.  It isn't actually waiting for network.  it is just waiting for rendering work.

Cheers!

--
You received this message because you are subscribed to the Google Groups "web-vitals-feedback" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web-vitals-feed...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/web-vitals-feedback/3cd70a98-d7a5-4d51-9322-9f0e8d7b3675n%40googlegroups.com.

Sander van Surksum

unread,
Nov 7, 2023, 8:18:48 AM11/7/23
to web-vitals-feedback
So what you're actually saying is that the network handler and image decoding is blocking the main thread (even due to the fact that image decoding is happing off the main thread)

About your last point. 

  • If your image was not already loaded at all by the time of interaction, it won't block rendering and so wont affect INP.
This was not exactly what I was experiencing during testing. I created a new demo where I changed the image toggles to buttons so the images are not loaded before clicking the button and there you see that INP is infected if you click a button before the previous image is fully loaded. 

ps Thanks for helping me understand how this actually works in the browser

Michal Mocny

unread,
Nov 7, 2023, 10:19:37 AM11/7/23
to Sander van Surksum, web-vitals-feedback
I just tested again.  I don't ever see any explicit blocking on the network.  Which is good, because INP should never measure network.

However, what I do see is that network response for the images does add Long Tasks and long running rasterization work to the page, and that in turn may affect interactions.  On your example page, none of your event handlers themselves are slow, it's just that if there happens to be any long running work processing these huge images while they are loading, interactions become affected by these huge workloads -- either via input delay blocked on previous frame Commit, or via presentation delay of the Interaction's animation frame, waiting for current frame Commit or off-main GPU rasterization for sync image decode.


I also noticed that even after the images are fully loaded and fully decoded once, as you switch back and forth between them each interaction may or may not continue to be slow.  I think that is because your click handler is wrapped with a React.startTransition (I am not sure, I am reading minified code).  State updates / effects inside startTransitions are supposed to be delayed and time sliced in idle time... but it is not actually guaranteed to wait until the next animation frame.  Because your event handler + Component render() is so fast, I think your transitions sometimes apply dom updates in the same frame.

I have had that happen to me with React before.  There are way to explicitly delay the transition until after next paint -- but in this case, I think you are much better served just fixing the problem: reduce the costs of these images, as you have already done.

Cheers.


Reply all
Reply to author
Forward
0 new messages