I've been trying to improve the web.dev rating for my website, and the last thing I'm struggling at is the LCP. The load delay is often really high and I struggle to understand why. Here's an example of my latest test:
Phase | % of LCP | Timing |
---|---|---|
TTFB | 12% | 650 ms |
Load Delay | 77% | 4.260 ms |
Load Time | 1% | 60 ms |
Render Delay | 10% | 570 ms |
The LCP we're talking about is an image. This is what the img tag looks like: <img class="img-fluid" fetchpriority="high" loading="eager" alt="Van houtwolisolatie tot schelpen: welke natuurlijke isolatiematerialen zijn er?" width="1024" height="768" src="https://livios-images.imgix.net/livios/umbracomedia/100432/renovatie%20kalkhennep2.jpg?w=640&h=480&auto=format&fit=crop&crop=faces%2Cfocalpoint&corner-radius=10&mask=corners&s=0cd046a70dfd52ab8c40029eafd14e99">
As you see I added fetchpriority="high"
and loading="eager"
to improve load.
In the head of my html I also added <link rel="preconnect" href="https://livios-images.imgix.net" crossorigin="">
and <link rel="dns-prefetch" href="https://livios-images.imgix.net">
to improve DNS loading. And I even added <link rel="preload" href="https://livios-images.imgix.net/livios/umbracomedia/100432/renovatie%20kalkhennep2.jpg?w=640&h=480&auto=format&fit=crop&crop=faces%2Cfocalpoint&corner-radius=10&mask=corners&s=0cd046a70dfd52ab8c40029eafd14e99" as="image">
to preload the image. Yet the load delay is still so high. Is there anything I'm missing?
First up it should be remembered that the Lighthouse proportion of PageSpeed Insights is a simulated test, under specific conditions that may or may not reflect your users actual experience. Your Core Web Vitals from real users look great for LCP! So this may not actually be an issue. But still, more head room is always better!
I'm not able to see such a high load delay myself (I get a 2.5 second load delay, rather than the 4.3 seconds you're seeing). Perhaps that was before you made some of these optimisations? But either way it can be improved.
As you see I added fetchpriority="high" ... to improve load.
Great! This is one of the best things you can do to improve load delay. But there's a subtle twist coming at the end of this answer.
... and loading="eager" to improve load.
loading="eager"
doesn't actually do anything btw. It doesn't make it any more "eager" than just not including the attribute. The default is loading eagerly anyway, it's just loading="lazy"
that makes it slower. loading="eager"
can be useful if your CMS or build tool defaults to loading="lazy"
unless you explicitly set it to eager
, but other than that it doesn't do anything. Still no harm to have it there.
In the head of my html I also added
You shouldn't have the crossorigin
attribute as images are typically not fetched in "crossorigin" mode (fonts and XHRs are), so this is a wasted preconnect.
In theory you shouldn't need this if the image is found reasonably quickly in the HTML (either as a preload, or an actual <img>
- as you have), but every little helps. Just make sure you're setting up the right preconnect by dropping the crossorigin
attribute. At the moment you're wasting valuable bandwidth setting up a connection you will not use.
and to improve DNS loading.
This is a bit of duplication of the preconnect
(it has to do a DNS lookup to do a preconnect!), so again isn't really needed. I'd remove it as preconnect
support is great, so really is unnecessary.
And I even added to preload the image. Yet the load delay is still so high.
Ah this is actually a problem! And a common one I see.
You are saying preload this image, but you have not given this a fetchpriority="high"
attribute so it preloads it with the default "low" priority of images (which is then bumped up to "high" later when it sees it's an onscreen image, but that's often too late). In effect, you are not benefiting much from this preload.
In fact, by preloading without fetchpriority=high
, you're actually causing more problems than you're resolving if the browser found the <img>
element later with that attribute!
Again, in theory, you should not need to preload this image (as it should be found pretty quickly as it's in the HTML), but if you want to preload it, to make it load ASAP, then make sure you give it a fetchpriority=high
attribute. Preload does not do this by default.
With this fetchpriority=high
attribute, the preloaded image might be load a little faster than it would without, as it could get in ahead of the fonts as looks like you preload it before them in the HTML.
So, that's my advice:
crossorigin
attribute from the preconnectdns-prefetch
as not needed due to the preconnect
preload
properly with fetchpriority=high
, or drop it completely.In all cases however, there is a price to pay by having the images hosted on a third-party domain as can be see with this waterfall:
You can see the cost of the new connection set up here on line 7 (the LCP line) before the image can even be downloaded.
Appreciate this is an image CDN (and it's the same one we use on web.dev btw!) and there are definite advantages to image CDNs, but one of the disadvantages is the delay caused by the connection set up cost :-(
So likely the above change will mitigate it as best you can, but there still be be a cost to page. Especially on the first page load of that site (and PageSpeed Insights always does an initial load so will always get this cost). Really users, will benefit from not having to pay this set up cost again on additional page loads as they browse around the site (which is likely one reason your real user LCP is better than the Lighthouse one).