How to Fix “Largest Contentful Paint Image Was Lazily Loaded” in WordPress

How to Fix “Largest Contentful Paint Image Was Lazily Loaded” in WordPress

When running a Google PageSpeed Insights or Chrome Lighthouse performance audit on your WordPress site, few warnings are as frustrating—or as common—as “Largest Contentful Paint image was lazily loaded”. This diagnostic flag directly degrades your Core Web Vitals score, inflating your Largest Contentful Paint (LCP) duration and penalizing your organic search rankings.

While lazy loading is generally hailed as an essential performance best practice for offscreen assets, applying it blindly to the main hero or featured image causes significant rendering delays. In this comprehensive technical guide, we will analyze why WordPress automatically lazy-loads hero images, explore the exact browser parsing sequence that triggers this penalty, and implement rock-solid code snippets to fix the issue permanently without relying on heavy plugins.

Understanding the Largest Contentful Paint (LCP) Metric

As defined in Google’s official web.dev Core Web Vitals documentation, Largest Contentful Paint measures the render time of the largest image, video poster, or block-level text element visible within the initial user viewport. For most content-driven WordPress websites, blogs, and ecommerce landing pages, the LCP element is almost always the post featured image or top hero banner.

To deliver a “Good” user experience, Google requires your LCP to occur within 2.5 seconds of the initial page navigation. When an LCP element takes between 2.5 and 4.0 seconds, it is classified as “Needs Improvement”, while anything exceeding 4.0 seconds is deemed “Poor”. Because LCP is heavily weighted within Google’s Search signals, eliminating artificial rendering delays on your primary viewport image is paramount for technical search engine optimization (SEO).

Why Does WordPress Lazily Load the LCP Image?

Beginning in WordPress 5.5, the core engineering team introduced native HTML lazy loading by automatically appending the loading="lazy" attribute to all content images and featured thumbnails. As outlined in the official Make WordPress Core release announcement, this architectural shift was designed to conserve network bandwidth by preventing offscreen images from downloading until the user scrolls near them.

However, native lazy loading operates under strict heuristics. Although WordPress 5.9 and subsequent core updates implemented logic to bypass lazy loading on the very first image detected on the page, real-world themes frequently break this heuristic. Common causes include:

  • Custom Header & Slider Elements: Themes that render site logos, navigation icons, or utility banners above the content trick the core parser into exempting those tiny icons instead of the true post hero image.
  • Full-Site Editing (FSE) & Page Builders: Tools such as Elementor, Divi, Beaver Builder, and block themes construct DOM trees where featured images are rendered inside nested query loops or custom template parts, preventing WordPress from recognizing them as the primary viewport asset.
  • Third-Party Optimization Plugins: Many caching and speed optimization plugins inject aggressive JavaScript-based lazy loading across all <img> tags unconditionally.

The Browser Execution Bottleneck: Why Lazy Loading Breaks LCP

Chrome Lighthouse audit showing 100 Performance score and passed LCP audit
Lighthouse audit confirming Largest Contentful Paint image was not lazily loaded

To appreciate why Chrome Lighthouse flags this issue, consider how the browser’s rendering engine processes a web document, as described in the official MDN HTML image loading documentation:

  1. HTML Tokenization & Preload Scanner: Modern browsers run a background preload scanner ahead of the main parser. When it encounters standard <img> tags, it immediately initiates network requests to fetch the graphic assets in parallel with CSS and DOM building.
  2. The loading="lazy" Deferral: When the browser detects loading="lazy" on an element, the preload scanner refuses to initiate the high-priority download. Instead, the browser defers fetching the image until the layout is fully calculated and the layout engine confirms that the image intersects with or is proximate to the viewport.
  3. Layout Cascading Delay: Because the browser must parse all stylesheets, construct the render tree, and perform geometric layout computations before determining that the hero image is indeed inside the viewport, your image request is delayed by hundreds of critical milliseconds.

This avoidable delay pushes LCP well past the 2.5-second threshold, producing the exact warning displayed in your Lighthouse report.

Step-by-Step Fix: How to Disable Lazy Loading on the First Image

The cleanest and most robust way to solve this issue across your entire WordPress site is to hook into WordPress core filter hooks. You do not need to install an extra plugin; simply add these lightweight PHP functions to your child theme‘s functions.php or via a site-specific code snippet plugin.

Method 1: Using the wp_omit_loading_attr_threshold Filter

WordPress provides a dedicated filter to define how many early images should be exempted from native lazy loading. By default, this threshold is set to 1 (or 3 in newer core releases for query loops). You can increase this threshold using this snippet:

/**
 * Increase the number of images excluded from native lazy loading in WordPress.
 * Ensures the hero image and top viewport assets load immediately.
 */
add_filter( 'wp_omit_loading_attr_threshold', function( $threshold ) {
    // Increase threshold to 3 images to safeguard against headers and logos
    return 3;
} );

Method 2: Target the Post Featured Image Directly via wp_get_attachment_image_attributes

If your hero image is rendered using standard WordPress template functions such as the_post_thumbnail() or wp_get_attachment_image(), you can explicitly remove the loading attribute while simultaneously adding fetchpriority="high":

/**
 * Strip loading="lazy" and add fetchpriority="high" to the primary post thumbnail.
 */
function netutility_optimize_hero_lcp_image( $attr, $attachment, $size ) {
    // Only target single posts and main query viewports
    if ( is_singular() && in_the_loop() && is_main_query() ) {
        // Remove lazy loading completely
        unset( $attr['loading'] );
        
        // Instruct browser to fetch immediately with highest network priority
        $attr['fetchpriority'] = 'high';
        $attr['decoding'] = 'async';
    }
    return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'netutility_optimize_hero_lcp_image', 10, 3 );

For a detailed breakdown of how to pair this with priority hints, see our companion tutorial on how to add fetchpriority=”high” to a WordPress featured image, as well as our complete architectural guide to excluding the featured image from lazy loading.

LiteSpeed Cache media settings excluding hero image from lazy loading
LiteSpeed Cache and plugin settings for excluding above-the-fold viewport thumbnails

If you prefer configuring existing caching plugins, verify that their lazy loading exclusion rules are properly defined:

1. LiteSpeed Cache

  1. Navigate to LiteSpeed Cache > Page Optimization > Media Settings.
  2. Locate the Lazyload Image Excludes text area.
  3. Add the class name of your theme’s featured image container (e.g., wp-post-image, attachment-post-thumbnail, or hero-header-img).
  4. Scroll down to Lazyload Image Top X and set the value to 2 or 3.

2. WP Rocket

  1. Navigate to Settings > WP Rocket > Media.
  2. Under the Exclude images or iframes textarea, enter the URL pattern or class attribute of your hero images (e.g., wp-post-image or featured-image).
  3. Save changes and clear your cache.

Comparison Matrix: Optimization Strategies for Viewport Images

TechniquePrimary BenefitLCP ImpactRecommended Usage
Remove loading="lazy"Allows preload scanner to detect image immediatelyReduces LCP by 200–500msMandatory for top hero element
Add fetchpriority="high"Boosts network priority over non-critical CSS/fontsReduces LCP by 150–350msApply to primary LCP element only
Preload via <link rel="preload">Starts network download before CSS/DOM tree parsesReduces LCP by 300–800msCritical for CSS background heroes
Modern AVIF / WebP FormatsCuts payload size by 30–60% without quality lossDrastically shortens download phaseSitewide recommendation

To take your performance optimizations to the highest tier, discover how to combine these techniques by reading our dedicated walkthrough on how to preload a WordPress hero image without a plugin.

Verification and Testing in Chrome DevTools

Chrome DevTools Elements panel inspecting optimized hero image markup
DevTools DOM inspection showing fetchpriority=’high’ and absent lazy loading

Once you have implemented your code or plugin exclusion, verify the fix using Chrome DevTools:

  1. Open your published post in Google Chrome using an Incognito window.
  2. Press F12 or right-click the hero image and select Inspect.
  3. Examine the <img> element attributes. Confirm that loading="lazy" is absent, and fetchpriority="high" is present.
  4. Switch to the Network tab, filter by Img, and reload the page with throttling set to Fast 4G.
  5. Confirm that the hero image appears in the top initial batch of requested assets with an initial priority of High.
  6. Run a fresh audit in the Lighthouse tab. The warning “Largest Contentful Paint image was lazily loaded” will now be completely resolved, returning a pristine green score.

Summary Checklist

  • Identify whether your LCP element is a featured image, slider, or CSS background graphic.
  • Ensure the first 1–3 viewport images are never assigned loading="lazy".
  • Inject fetchpriority="high" to instruct the browser network queue to prioritize your hero asset.
  • Clear your object cache, page cache, and CDN edge cache before re-testing in PageSpeed Insights.
James Parker

James Parker

James Parker is a technology writer and WordPress enthusiast who shares practical guides on SEO, web development, AI tools, and digital growth. He focuses on creating easy-to-follow tutorials that help beginners and professionals build better websites and improve their online presence.