CDN & Caching Strategies

Fix “LCP Image Was Lazily Loaded” in WordPress (3 Methods)

Run PageSpeed Insights on your homepage and you may see a warning like this: “LCP image was lazily loaded.” It sounds minor, but it is one of the most common reasons WordPress sites fail Largest Contentful Paint. The good news is that it is also one of the easiest to fix.

Lazy loading is great for images below the fold. But when your hero image, the big image at the top of the page, gets lazy loaded, the browser deliberately holds back the most important visual element on the page. LCP time climbs, the score drops, and visitors stare at a blank space where the headline image should be.

Here is how to fix it in WordPress. Three methods below, depending on how hands-on you want to be.

The short answer: the image behind your Largest Contentful Paint should load eagerly with fetchpriority="high", never lazy. Use a WordPress core filter, a setting in LiteSpeed Cache, WP Rocket, or Perfmatters, or hard-code it in your theme. Then verify in DevTools.

Why This Warning Hurts Your Score

Largest Contentful Paint measures when the largest visible element, usually a hero image or headline block, finishes rendering. Lazy loading tells the browser: do not download this image until it is near the viewport. For an image already in the viewport on page load, that instruction is pure delay. The browser waits, discovers the image late, and only then starts downloading it.

Google’s own guidance is blunt: the LCP image should be discoverable in the initial HTML and loaded with high priority. Lazy loading it does the exact opposite.

Before You Fix: Identify Your LCP Image

You cannot fix what you cannot find. In PageSpeed Insights:

  1. Run a test and scroll to the Diagnostics section.
  2. Look for the LCP element. PSI names it explicitly (e.g., “img.hero-image” or a specific URL).
  3. Note the image URL and where it appears (hero section, featured image, slider).

Now pick your method.

Method 1: Let WordPress Core Handle It (Easiest)

Since WordPress 6.3, core automatically adds fetchpriority="high" to the image it detects as most likely to be the LCP element, typically the first large image in the content. For many standard themes and the block editor, this already works out of the box.

But themes and page builders sometimes output their own <img> tags that bypass this logic. To force the correct behavior on a specific image, add this to your child theme’s functions.php or a code snippets plugin:

add_filter( 'wp_get_attachment_image_attributes', function( $attr, $attachment ) {
    // Replace 123 with the attachment ID of your hero/LCP image.
    if ( $attachment->ID === 123 ) {
        $attr['fetchpriority'] = 'high';
        $attr['loading'] = 'eager';
        unset( $attr['decoding'] ); // optional: let the browser decide
    }
    return $attr;
}, 10, 2 );

How to find the attachment ID: open the image in your Media Library. The URL in the address bar contains post=123, and that number is the attachment ID.

This approach is surgical: it changes exactly one image and nothing else. If your LCP image comes from a page builder widget instead of the media library, skip to Method 2 or 3.

Method 2: Exclude the Image in Your Optimization Plugin

Most optimization plugins lazy-load aggressively by default, which is exactly how the hero image ends up lazy. The fix is to exclude the LCP image from lazy loading. Here is where to look in the popular plugins:

LiteSpeed Cache

Go to LiteSpeed Cache → Page Optimization → Media Settings:
– Find Lazy Load Image Excludes and add a selector for your hero image (e.g., .hero-image, #hero img, or part of the image URL like hero-banner.jpg).
– Make sure Lazy Load Above the Fold is set to exclude above-the-fold images (the default behavior in recent versions is to skip the first few images, but verify).

WP Rocket

Go to Settings → WP Rocket → Media:
– In LazyLoad, add the image to Excluded images or iframes (you can use the filename, a CSS class, or part of the URL).
– WP Rocket also has an “Add missing image dimensions” option nearby; enabling it helps prevent layout shift on the same hero image.

Perfmatters

Go to Perfmatters → Lazy Loading:
– Use Exclusions to add the image URL, filename, or a CSS selector (e.g., no-lazy class).
– Pro tip: add a no-lazy class to your hero image in the editor, then exclude that class. It survives image replacements without you having to update URLs.

After changing any of these settings, purge all caches before re-testing: the plugin cache, and your CDN cache if you use one (our guide shows how to test whether your CDN is actually serving cached content).

Method 3: Hard-Code It in the Theme (Most Reliable)

If your hero image is part of the theme template, a common case with custom themes and page builders, the cleanest fix is to edit the markup directly so the <img> tag reads:

<img src="hero.jpg" alt="..." fetchpriority="high" loading="eager" width="1600" height="900">

Three things matter here:

  1. fetchpriority="high": tells the browser to download this image before other resources.
  2. loading="eager": explicitly opts out of lazy loading (this is the default, but stating it defeats plugin-level lazy loading that rewrites the tag).
  3. width and height: prevents layout shift (CLS), the other metric that hero images love to ruin.

In Elementor, you can set this without code: select the image widget and look for lazy-load controls in the widget settings, or use Method 2’s exclusion with the widget’s CSS class. In the block editor, select the image block and check the Advanced panel.

Verify the Fix in DevTools

Do not trust the settings screen. Verify what the browser actually receives:

  1. Open your homepage in Chrome, press F12, go to the Network tab.
  2. Reload the page and filter by Img.
  3. Click your hero image and check the response/request headers panel. Or simpler: right-click the image → Inspect, and look at the <img> tag in the Elements panel.
  4. Confirm the tag shows loading="eager" (or no loading attribute at all, since eager is the default) and fetchpriority="high".
  5. In the Network tab, check the Priority column: your hero image should show High.

Then re-run PageSpeed Insights. The “LCP image was lazily loaded” warning should be gone, and your LCP time should drop, often noticeably. You just removed an artificial delay from the single most important resource on the page.

What If the LCP Element Is a Background Image?

CSS background images cannot take loading or fetchpriority attributes. That is a common trap. If PSI says your LCP element is a background image (a div with a background), you have two honest options:

  1. Convert it to a real <img> where possible. Real images get priority hints, responsive srcset, and lazy-load control. Backgrounds get none of that.
  2. Preload it by adding this to your <head>:
    html
    <link rel="preload" as="image" href="/wp-content/uploads/hero.jpg" fetchpriority="high">

    This tells the browser to discover the image early even though it is referenced from CSS.

Frequently Asked Questions

Will removing lazy load from one image slow down my site?

No. You are removing lazy loading from exactly one image — the one already visible on screen, which the browser has to download immediately anyway. Every other image keeps lazy loading. The net effect is faster, not slower.

Does WordPress lazy-load images by default?

Yes — since WordPress 5.5, core adds loading="lazy" to images that have width and height attributes. Since 6.3, it also tries to detect the likely LCP image and give it fetchpriority="high" instead. Plugin-level lazy loading can override or duplicate this, which is why exclusions matter.

Can I just disable lazy loading entirely?

You could, but you should not. Lazy loading below-the-fold images is a genuine performance win — it saves bandwidth and speeds up initial rendering. The correct fix is selective: eager-load the LCP image, lazy-load everything else.

My page builder keeps re-adding lazy load. What now?

Some builders rewrite image markup on save or apply their own lazy loading. Use the builder’s own exclusion settings first (Elementor, Divi, and Beaver Builder all have them), then your optimization plugin’s exclusion list as a second layer. Verify in DevTools after every change — that is the only source of truth.

Should I also preload the LCP image?

Preloading (<link rel="preload" as="image">) helps when the image is hard for the browser to discover early — CSS backgrounds, images injected by JavaScript, or deeply nested markup. For a standard <img> in the initial HTML with fetchpriority="high", preloading adds little. Do one or the other well, not both sloppily.

The Bottom Line

“LCP image was lazily loaded” is a self-inflicted wound. Your optimization stack is delaying the one image that matters most. Exclude the hero image from lazy loading, give it fetchpriority="high", and verify in DevTools. It takes ten minutes. It is one of the highest-ROI fixes in all of WordPress performance work, and it pairs naturally with the rest of our 20-step WordPress performance checklist.