Lazy loading is one of the first things anyone recommends when a WordPress site is slow. Defer the images below the fold until the visitor scrolls to them, and the initial page payload shrinks, load times drop, and your Core Web Vitals improve.
Most of that is true. The part that gets skipped is that lazy loading the wrong image does the opposite.
If your hero image, your featured image, or anything else visible without scrolling carries loading=”lazy”, you are delaying your Largest Contentful Paint (LCP) on purpose. This is not a fringe problem. When HTTP Archive looked at mobile pages that lazy load their LCP image in the 2022 Web Almanac, 72% of them ran on WordPress, even though WordPress powered about 35% of pages overall. Google’s own web.dev analysis found that pages using lazy loading had a slower median LCP than pages without it, and flagged over-application to above-the-fold images as the likely reason. That is correlation rather than proof, and web.dev says so, but it lines up with what we see in client audits.
This guide covers what lazy loading is, why “lazy load everything” backfires, which images to exclude, how to configure it with or without a plugin, and how we check it on client sites.
What Is Lazy Loading in WordPress?
Lazy loading is a browser feature that holds off on downloading images, videos, and iframes until they are about to enter the viewport. Instead of fetching every image on the page the moment someone lands on it, the browser only fetches what is visible. The rest load as the visitor scrolls.
On a long article with twenty images, the browser downloads the first two or three and leaves the other seventeen alone until they are needed. Less to download up front, and the page feels quicker.
WordPress has added the loading=”lazy” attribute to content images automatically since version 5.5. Chrome, Firefox, Safari, and Edge all support it natively, so no plugin or JavaScript is needed for the basic behaviour.
Automatic is not the same as correct, though. WordPress is guessing, server-side, which images will be visible. It has no idea how your theme lays the page out.
Why Lazy Loading the Wrong Images Kills Your LCP Score
If you take one thing from this article, take this section.
LCP is the time it takes for the largest visible element on your page to render. On most WordPress sites that element is an image: the homepage banner, the featured image at the top of a post, the product photo on a landing page.
Browsers run a preload scanner alongside the main HTML parser. Its job is to spot critical resources early and start fetching them before the page has finished parsing. Lazy images are skipped by that scanner entirely. So the browser downloads the HTML, the CSS, the JavaScript, works out the layout, realises the hero image is in view after all, and only then requests it. Your most important visual element ends up at the back of the queue.
In practice we have watched an LCP go from the low 1-second range to well over 3 seconds on the same page with no other change. That is the difference between passing and failing the assessment.
WordPress has tried to fix this in core. Version 5.9 stopped lazy loading the first content image. Version 6.3 went further: it skips lazy loading on the first few images and adds fetchpriority=”high” to the one it thinks is the LCP candidate. Those heuristics work on a plain blog layout. They break when a page builder like Elementor or Divi outputs its own image markup, when the hero is a CSS background image rather than an img tag, when a logo or header graphic comes before the main image in the source order, or when an optimisation plugin overrides core’s decisions. You cannot assume WordPress picked the right image.
The rule is short. Lazy load below the fold. Never above it.
Which Images Should and Should Not Be Lazy Loaded
Never lazy load these: the hero image or homepage banner, the featured image when it sits at the top of a post, the site logo and header image, and the primary product or service image on a landing page. Any of these can be the LCP element, and they should load with the highest priority the browser offers.
Lazy load these: body images that appear after a couple of paragraphs, gallery images below the fold, testimonial and team photos low on the page, footer graphics and sponsor logos, and anything else the visitor has to scroll to reach.
The test is simple. Open the page, do not scroll, and look at what you can see. Those images stay eager. Everything below that line is a candidate for lazy loading. Then do it again on a phone, because the fold sits in a very different place on a 375px screen.
How WordPress Lazy Loading Works Natively
Out of the box, WordPress adds loading=”lazy” to images in post content, leaves the first few content images eager, and marks the likely LCP image with fetchpriority=”high”. No configuration is required.
For a simple blog on a well-built block theme, that is often enough. The featured image loads eagerly and the in-content images defer.
It breaks down in three common situations. Page builders (Elementor, Divi, Beaver Builder) render images outside the standard content area with their own markup, so core’s logic may never touch the real LCP element. Custom themes that load the hero as a CSS background image are invisible to the loading attribute altogether, because it only applies to img tags. And caching or image plugins with their own lazy loading can override whatever core decided.
Treat native lazy loading as a starting point. If you run a page builder or a performance plugin, you need to verify it.
How to Add Lazy Load to WordPress Using Plugins
Plugins give you explicit control over which images defer and which do not. For most business sites this is the right approach.
WP Rocket (Recommended for Most Sites)
WP Rocket bundles lazy loading for images, iframes, and videos with caching, CSS and JavaScript optimisation, and database cleanup. Its Optimize Critical Images setting detects above-the-fold images and excludes them from lazy loading automatically, and on most sites we have tested it gets the LCP exclusion right without manual work.
To enable it: Settings, then WP Rocket, then the Media tab. Turn on lazy loading for images and iframes, turn on Optimize Critical Images, save, and test.
It is a paid plugin, starting around $59 a year for one site. For a business site where speed affects leads, that is not a hard sell.
Perfmatters
Perfmatters is a lighter performance plugin with fine-grained exclusions. You can exclude images by URL, by CSS class, or by telling it to skip the first N images on each page. If WP Rocket is more than you need, this is the precise alternative.
Smush
Smush is an image compression plugin first, but the free tier includes lazy loading with per-image exclusions. If you already use it for compression, enable lazy loading there rather than adding another plugin. Do not run Smush’s lazy loading alongside WP Rocket’s. Two implementations fighting over the same images is one of the most common causes of a broken LCP we see.
The “Lazy Load by WP Rocket” Plugin (Free)
A free standalone plugin from the WP Rocket team that handles images, iframes, and videos and nothing else. Good if you want plugin-level control without the full package.
How to Enable Lazy Loading Without a Plugin
If you would rather not add a plugin, or native lazy loading is misfiring on specific images, you can control it in the HTML directly.
Using the Native Loading Attribute
For any img tag in a theme template or page builder custom code, one attribute decides the behaviour. To lazy load an image below the fold:
<img src="image.jpg" loading="lazy" width="800" height="600" alt="Description">
To load a critical above-the-fold image as early as possible:
<img src="hero-banner.jpg" loading="eager" fetchpriority="high" width="1200" height="800" alt="Description">
The width and height attributes are not optional. They let the browser reserve space before the image arrives, which keeps your CLS down.
fetchpriority=”high” tells the preload scanner to fetch this image ahead of other non-critical resources. For a hero image it is the single most effective HTML change you can make.
Using WordPress Filters to Exclude Specific Images
If you are comfortable in functions.php or a code snippets plugin, you can tell core to skip lazy loading for a specific context:
add_filter( 'wp_lazy_loading_enabled', function( $default, $tag_name, $context ) {
if ( 'img' === $tag_name && 'the_post_thumbnail' === $context ) {
return false;
}
return $default;
}, 10, 3 );
This disables lazy loading for featured images output through the_post_thumbnail(), which is the most common LCP element on blog posts.
For more targeted control, add a class such as no-lazy to specific images in your builder and filter on that class instead.
How We Check This on Client Sites
Every technical audit we run at SEO24 includes the same lazy loading check, and it takes about ten minutes per template. We run the homepage, one service or product page, and one blog post through PageSpeed Insights on mobile and open the LCP diagnostic to see which element Google identified. Then we inspect that element in Chrome DevTools and look at three things: does it carry loading=”lazy”, does it carry fetchpriority=”high”, and is it an img tag at all or a CSS background. If the LCP image is lazy, we switch it to eager with fetchpriority=”high”, clear the cache, and re-run PageSpeed Insights so the client can see the before and after LCP side by side. We keep both screenshots in the audit report because the numbers make the argument better than we can.
The pattern we run into most often is not core WordPress getting it wrong. It is a caching or image plugin installed years ago with “lazy load all images” ticked, quietly overriding the fix that core shipped in 6.3.
Lazy Loading and Image Formats
Lazy loading controls when an image loads. Format controls how heavy it is when it does. You need both.
AVIF is the current best option. Files come in roughly 30 to 50% smaller than WebP at the same visual quality, and every major browser now supports it. On image-heavy sites, moving the primary format to AVIF is usually the largest single LCP improvement available.
WebP is the reliable fallback: 25 to 35% smaller than JPEG at similar quality, supported everywhere, and accepted by the WordPress media library since version 5.8. If you are not serving WebP yet, start there.
JPEG and PNG still have a place as final fallbacks, but they should not be what most visitors receive.
In practice: use an image optimisation plugin (ShortPixel, Imagify, or Smush) that converts uploads to WebP or AVIF and serves the right format per browser. Pair that with lazy loading for below-the-fold images and you have addressed the two biggest causes of slow LCP on WordPress.
And compress before you upload. A hero image straight off a camera at 4 to 8MB should be under 200KB before it touches the media library. The images that do load immediately need to load fast.
Lazy Loading Videos and Iframes
The same logic applies to embeds. A YouTube or Vimeo iframe loaded eagerly pulls in the whole player, its JavaScript, and its thumbnails on page load, even when the video sits at the bottom of the article.
Add loading=”lazy” to iframes the same way you would to images:
<iframe src="https://www.youtube.com/embed/VIDEO_ID" loading="lazy" width="560" height="315"></iframe>
For YouTube in particular, a facade is even better. Show the thumbnail as a static image and only load the real player when someone clicks. WP Rocket and several dedicated facade plugins do this automatically.
How to Test Whether Your Lazy Loading Is Working Correctly
Check the LCP element first. Run your homepage and key landing pages through PageSpeed Insights and open the LCP diagnostic. It names the element and shows how long it took. A hero image over 2.5 seconds with loading=”lazy” on it is your fix.
Check the HTML. Right-click the hero image, choose Inspect, and read the img tag. If loading=”lazy” is there, change it to loading=”eager” and add fetchpriority=”high”.
Check Search Console. Under Experience, then Core Web Vitals, look for pages marked Poor or Needs Improvement on LCP. Search Console reports real CrUX field data over a rolling 28-day window, so a fix made today shows up roughly four to six weeks later.
Scroll the page. Below-the-fold images should show a slight delay as you reach them. If everything loads instantly, lazy loading is off. If the hero hesitates before appearing, it is being deferred when it should not be.
Common Lazy Loading Mistakes That Hurt WordPress SEO
Lazy loading the LCP image. The whole article is about this one, but it bears repeating. Check every key template.
Running more than one lazy loading implementation. WP Rocket plus Smush plus a3 Lazy Load all active at once produces unpredictable results. Pick one, disable the rest.
Skipping image dimensions. Images without width and height attributes shift the layout as they load. Every image needs both.
Forgetting the mobile fold. More images are above the fold on a 375px phone than on a 1920px monitor. An image safely deferred on desktop can be the LCP on mobile. Test both.
Trusting the Lighthouse score. Lighthouse is a lab test. Google ranks on CrUX field data. A 95 in Lighthouse does not mean you pass Core Web Vitals in Search Console.
Lazy Loading and Its Connection to Your Broader SEO Performance
Lazy loading is one piece of a larger page speed and technical SEO picture. It decides when images load. The rest of the stack decides how heavy the page is in the first place.
Perfect lazy loading on a site with 5MB uncompressed images, no caching, and slow hosting still fails Core Web Vitals. Image optimisation handles file weight. Caching cuts how often the server rebuilds a page. A CDN shortens the distance to the visitor. Good hosting keeps the server response fast. The theme sets the baseline for all of it; a heavy theme ships hundreds of kilobytes of CSS and JavaScript before any image loads, which is why we filter candidates by payload in our guide on how to choose a WordPress theme.
Our guide on tools to improve WordPress page load time covers the full stack that sits around lazy loading, and our WordPress speed optimisation article walks through the order we do it in. If your Core Web Vitals are still struggling after the lazy loading fix, hosting and caching are usually next.
For WordPress sites built for business, speed feeds straight into leads. A page that loads in under two seconds converts measurably better than one that takes four, whatever the design. The organic traffic those improvements unlock compounds: better Core Web Vitals lift rankings, more visibility brings more visitors, and faster pages convert more of them.
Frequently Asked Questions: Lazy Loading in WordPress
Does WordPress have lazy loading built in?
Yes. Since version 5.5 WordPress adds loading=”lazy” to images in post content. Since 5.9 it leaves the first content image eager, and since 6.3 it skips the first few images and adds fetchpriority=”high” to the likely LCP image. For a simple blog that is usually enough. For sites using page builders or performance plugins, verify it against your actual layout.
Should I lazy load my hero image in WordPress?
No. Never lazy load your hero image, the featured image at the top of a post, or anything visible without scrolling. These are potential LCP elements, and deferring them delays their render directly. Use loading=”eager” and fetchpriority=”high” on above-the-fold images instead.
What is the best WordPress lazy loading plugin?
WP Rocket is the most complete option, with automatic LCP image detection and exclusion. Perfmatters is a lighter alternative with granular exclusion controls. Smush combines image compression with lazy loading. Whichever you pick, run only one lazy loading implementation at a time.
Does lazy loading help with Core Web Vitals?
Yes, when applied to below-the-fold images. It reduces the initial payload, which frees bandwidth for above-the-fold content and helps LCP. With proper image dimensions it also helps CLS. Lazy loading the LCP element itself does the reverse and hurts LCP significantly.
How do I exclude an image from lazy loading in WordPress?
Add loading=”eager” directly to the img tag in custom HTML. In WP Rocket, use Optimize Critical Images or add the image URL to the exclusion list. In Perfmatters, exclude the first N images or a specific CSS class. In Smush, exclude images individually in the Lazy Load settings.
Does lazy loading affect image SEO?
Not when it is done with the native loading=”lazy” attribute, which Google indexes normally. Problems come from JavaScript lazy loaders that put the image URL in a data-src attribute instead of src, which can stop Google from discovering the image. Stick to native lazy loading or plugins that keep standard HTML attributes.
How do I check if lazy loading is hurting my LCP?
Run your key pages through PageSpeed Insights and open the LCP diagnostic. If the LCP element is a hero image loading in over 2.5 seconds, right-click it, choose Inspect, and look for loading=”lazy” in the HTML. If it is there, switching it to eager is usually an immediate LCP improvement. A free SEO audit will surface this alongside other technical issues.
What image format should I use with lazy loading?
AVIF is the best current option, roughly 30 to 50% smaller than WebP at the same visual quality. Use WebP as the fallback and JPEG or PNG as a final fallback for older browsers. Image optimisation plugins like ShortPixel and Imagify handle the conversion and browser detection automatically.
Getting WordPress performance right means looking at lazy loading, image formats, caching, and hosting together rather than fixing one in isolation. The SEO24 team in Toronto helps WordPress businesses find exactly what is holding their Core Web Vitals back and fix it in the right order. Our WordPress maintenance and support service keeps your site fast and optimised on an ongoing basis. Start with a free SEO audit to see where your site stands today.
