Fix the Largest Contentful Paint image was lazily loaded in lighthouse
Learn how to fix the lighthouse warning 'Largest Contentful Paint image was lazily loaded'
Largest Contentful Paint image was lazily loaded - in short.
Lazy-loading the Largest Contentful Paint image will trigger a lighthouse warning. Lazy loaded images will get queued for downloading at a much later time the non-lazy (eager) images. This will cause the Image to render later and delay the Largest Contentful Paint metric.
Table of Contents!
- Largest Contentful Paint image was lazily loaded - in short.
- What is the 'Largest Contentful Paint image was lazily loaded' warning?
- A quick reminder: lazy loading
- How does a 'lazy loading Largest Contentful Paint image' affect pagespeed?
- How to fix 'Largest Contentful Paint image was lazily loaded'
Browsers are smart enough to figure this out right? Yes, browser are pretty smart, but not in this case!
When you lazy load an image element you explicitly tell the browser to de-prioritize this image.
This means all the other non-lazy images will get scheduled for download earlier then your lazy images. When this lazy image is your LCP element you will probably delay your LCP. Maybe even by a lot!
Things get even worse when you use Java-script based lazy loading libraries like lazysizes.js. Now the browser does not only delay your LCP image element, you even have to wait for JavaScript to be downloaded and executed.
Fix the lighthouse warning by removing the loading="lazy" attribute from your LCP image or by updating the filters on your plugins to bypass lazy loading for the LCP image.
What is the 'Largest Contentful Paint image was lazily loaded' warning?
This warning that is given when the Largest Contentful Paint image is lazy-loaded by the browser. Why? Because lazy-loading the most important image on the page (the Largest Contenful Paint element) is a bad idea. For pagespeed purposes you should load this element as early as possible. Lazy loading this element might delay the Largest Contentful Paint.
A quick reminder: lazy loading
Lazy loading is when an element, often an image, is not scheduled for download by the browser, immediately during page load but rather when the element is close to the visible part of the screen. There are 2 methods of lazy loading.
Native lazy loading
Native lazy loading uses the browsers native lazy loading API. For images it is as simple as adding loading="lazy" to the image tag. Native lazy loading is currently supported by all modern browsers.
<img loading="lazy" src="image.png" width="123" height="123" alt="a lazy loaded image" >
JavaScript based lazy loading
JavaScript based lazy loading uses a JavaScript API called the intersection observer to determine when an image is in or close to the visible viewport. When in image is in the visible viewport the image src is swapped for the final image. Usually you can recognize JavaScript based lazy loading by the data-src attribute on the image. JavaScript lazy loading is supported by even more browsers but has a serious disadvantage: 'it uses JavaScript'. In order for lazy loading to even begin a JavaScript file has to be downloaded. This means that JavaScript based lazy loading can never be as fast and efficient as native lazy loading
<img data-src="image.png" src="small-placeholder.png" width="123" height="123" alt="a lazy loaded image" >
How does a 'lazy loading Largest Contentful Paint image' affect pagespeed?
Lazy loading that element will delay the moment the LCP image is painted on the screen. This will cause a visitor to believe the page loads slower because ti takes a longer time to be 'visually ready'
The most important image, often the LCP element should be loaded immediately to ensure it can be painted on the screen as fast as possible.
Now you might think that a browser would be smart enough to figure this out? You are mistaken! When you lazy load an image element you explicitly tell the browser to de-prioritize this image. This means all the other non-lazy images will get scheduled for download earlier then your lazy images. When this lazy image is your LCP element you will probably delay your LCP. Maybe even by a lot!
Things get even worse when you use Java-script based lazy loading libraries like lazysizes.js. Now the browser does not only delay your LCP image element, you even have to wait for JavaScript to be downloaded and executed.
Just take a look at this chrome network tab where I lazy loaded the LCP image (HERO.jpg) and eager loaded 6 other images. You will see that the HERO image is the last image to start downloading and also the last image to finish downloading!
A bit more detail
Now let's get a bit more technical. Why can't a browser figure this out on it's own? That is, with lazy loading, you are specifically instructing a browser to de-prioritize an image. In many cases this will mean a browser will start downloading other resources first. An exactly that is cause the delay in LCP.
- Lazy images will get queued for downloading at a much later time then non-lazy (eager) images.
- Lazy images often get downloaded with low priority.
- Other elements like normal images, deferred scripts, fonts etc might be scheduled for download earlier then lazy images.
- JavaScript based lazy loading depends on a JavaScript that has to download and execute before lazy loading can even begin.
How to fix 'Largest Contentful Paint image was lazily loaded'
Fixing the waring about the lazy Largest Contentful Paint image is straightforward. Just do not lazy load this image.
In theory
- If you are using native lazy loading remove the loading="lazy" from the LCP element or change it to loading="eager"
- If you are using JavaScript based lazy loading you could consider switching to the faster native lazy loading or just omit the LCP image from lazy loading.
- If you are using some sort of image component like next/image set the strategy="eager".
In real life
In real life this might cause a few headaches. Many sites use optimization plugins that will lazy load all the images on the screen for you. Those plugins do not distinguish between important, always visible images and images below-the fold.
Most plugins will allow you to 'bypass lazy loading' based on filename, class name or other attributes. This means that you will have to read the documentation for you plugin or just google '[your plugin name] + bypass lazy loading'. Then edit your template file and change your main image accordingly or change the images in your page editor.
Workaround for 'Largest Contentful Paint image was lazily loaded'
Sometimes your CMS will not allow you to change the lazy loading settings of images. In that case there are still some workarounds you can use to minimize the impact.
- Lazy load all images to ensure below the fold 'eager' images are not downloaded before the LCP image
- Avoid background images to ensure no background iamges are downloaded before the LCP element
- Preload the LCP element. This will make sure the LCP image is scheduled for download as early as possible
- Disable JavaScript based lazy loading and switch to native lazy loading. This will at least remove the JavaScript delay
- Add fetchpriority = "high" to the LCP element. This will schedule the image for early download
- Optimize all your images. Use responsive images and Next-gen image formats to lower the time it will cost to download the images.
Stop Guessing, Start Measuring
I use Core/Dash to optimize my clients sites. So Should You.
- Easy set up.
- Over 5000 happy clients
- Free trial, No strings attached