WordPress Lazy Loading Breaking LCP — How to Fix It
WP Core's lazy-loading attribute defers your hero image, making LCP fail. Here's the 3-line fix that recovers your score.
WordPress 5.5 introduced automatic loading="lazy" on all images. It was a well-intentioned default — lazy loading below-the-fold images saves bandwidth and speeds up the page for most content. But it created a widespread regression for LCP, because WordPress applies the attribute to hero images too, and a lazily-loaded hero image is almost always the Largest Contentful Paint element.
The result: PageSpeed Insights flags your LCP as Poor, and your hero image is the culprit. Here's how to diagnose it and fix it without breaking anything else.
How to Confirm This Is Your Problem
Open PageSpeed Insights and run your homepage or landing page URL. In the Opportunities section, look for:
"Largest Contentful Paint image was lazily loaded"
That warning confirms the issue. PSI identified your LCP element as an image that has loading="lazy" applied, which means the browser won't start downloading it until the page structure is rendered — creating an artificial delay on the most important asset on the page.
You can also confirm by inspecting the hero image in your browser's developer tools. If the rendered HTML shows loading="lazy" on your above-the-fold hero image, that's your problem.
Fix 1: Add fetchpriority="high" to the Hero Image
The fastest fix for most sites. Add fetchpriority="high" to your hero image tag. This tells the browser to treat the image as a high-priority resource and begin fetching it as early as possible — before the parser would normally encounter it.
<img
src="hero.jpg"
alt="Hero image"
fetchpriority="high"
loading="eager"
width="1200"
height="630"
/>
Note the combination: fetchpriority="high" plus loading="eager". Setting fetchpriority alone helps, but explicitly removing loading="lazy" (or setting it to eager) ensures WordPress doesn't override your intent.
Fix 2: Remove loading="lazy" via the WordPress Filter
If you're working with a theme that outputs images through wp_get_attachment_image() or the block editor, you can intercept the attributes using the wp_get_attachment_image_attributes filter. Add this to your theme's functions.php or a site-specific plugin:
<?php
/**
* Remove lazy loading from the first image (LCP candidate).
* Adjust the logic to match your theme's hero image ID or context.
*/
add_filter( 'wp_get_attachment_image_attributes', function( $attr, $attachment, $size ) {
// Target your hero image by attachment ID, or by size
if ( 'hero' === $size || get_post_thumbnail_id() === $attachment->ID ) {
$attr['loading'] = 'eager';
$attr['fetchpriority'] = 'high';
}
return $attr;
}, 10, 3 );
This approach is more surgical than removing lazy loading globally. You keep the performance benefits for all below-the-fold images while fixing the LCP regression at the source.
If you want to disable automatic lazy loading entirely (useful if you're managing it manually or through a performance plugin), use:
<?php
// Disable WordPress automatic lazy-loading for all images
add_filter( 'wp_lazy_loading_enabled', '__return_false' );
Do this only if you have a plugin handling lazy loading selectively. Disabling it globally without a replacement will hurt page weight.
Fix 3: Add a Preload Link in <head>
For hero images that live in CSS backgrounds or come from a theme template rather than a media library attachment, the filter approach won't work. Use an explicit preload hint instead:
<link
rel="preload"
as="image"
href="/wp-content/uploads/2026/05/hero.jpg"
fetchpriority="high"
/>
Add this in your theme's header.php before any stylesheet links, or use wp_head in functions.php:
<?php
add_action( 'wp_head', function() {
echo '<link rel="preload" as="image" href="' . get_template_directory_uri() . '/images/hero.jpg" fetchpriority="high" />';
}, 1 ); // Priority 1 = outputs very early in <head>
The earlier this fires in <head>, the more effective it is. Priority 1 puts it before styles and scripts.
Plugin Alternatives
If you'd rather not touch code, two plugins handle this reliably:
WP Rocket — enables LCP preload image detection automatically. Under Settings > Media, it identifies the LCP element from PSI data and adds the preload hint. This is the most hands-off approach.
Perfmatters — under the Script Manager and Lazy Loading sections, you can exclude specific images from lazy loading by URL pattern or class. Less automated than WP Rocket, but lightweight.
What to Check After Fixing
Re-run PageSpeed Insights after applying your fix. The "Largest Contentful Paint image was lazily loaded" warning should be gone. LCP scores typically improve by 0.5–1.5 seconds on a properly fixed hero image, often moving from Poor or Needs Improvement into Good.
Also check:
- Lab LCP vs. Field LCP: PSI shows both. Lab data updates immediately; field data (from real Chrome users) takes 28 days to cycle through. Don't expect the CrUX field data to improve overnight.
- Mobile separately from desktop: WordPress responsive images behave differently at different breakpoints. Run PSI on the mobile tab too.
- Scroll depth: If your "hero" isn't above the fold on mobile (common with tall headers), PSI may identify a different element as LCP. Fix the right element.
For a broader look at LCP scoring and what element Google actually flags, see What Is a Good LCP Score?.
The Broader CWV Picture
Fixing the lazy-load LCP regression usually improves your score meaningfully, but it's rarely the only issue. If your LCP is still in the Poor range after this fix, the next culprits to investigate are:
- Slow server TTFB — if the server takes 600ms to respond, your LCP can't be fast regardless of image loading.
- Render-blocking CSS — large stylesheets that block painting delay LCP even for eager images.
- No CDN on images — images served from the origin server without a CDN add network latency on top of everything else.
RankCrab's audit surfaces all three CWV metrics alongside your other on-page issues, so you can see LCP, INP, and CLS scores in one place without running PSI manually on every page. Track your before/after scores as you push fixes so you have a clear record of what actually moved the needle.
For platform-specific INP issues in WordPress, see How to Fix High INP Score in WordPress. For the full Core Web Vitals overview, start at the Core Web Vitals guide.