You think you're optimizing your website. You might actually be slowing it down.
According to the 2025 Web Almanac, roughly 16% of mobile pages incorrectly apply lazy loading to their LCP image — the single largest content element in the viewport. This isn't a minor oversight. It tanks your Core Web Vitals scores, hurts your Google ranking, and drives users away before your content even loads.
The root cause? Misapplying a genuinely useful technique to exactly the wrong place.
Lazy Loading Isn't the Problem — Misuse Is
Lazy loading is sound in principle: defer loading off-screen content to reduce initial page weight. Used correctly, it can cut first-load time by 30–50%.
But there's a critical browser mechanism that most developers overlook: the Preload Scanner.
When a browser parses HTML, the preload scanner runs in parallel to discover resources and queue them for early download. This is one of the biggest performance wins in modern browsers. The moment you add loading="lazy" to an image, though, the preload scanner completely skips it, relegating it to the lowest priority at the back of the queue.
If that skipped image happens to be the largest element on your page — a hero image, main banner, product photo — your LCP time spikes dramatically.
Open Chrome DevTools and you'll see it instantly: on a page with 7 images, the one with lazy loading starts downloading last — even though it's visually the most important.
Both Types of Lazy Loading Are Problematic
Many projects use JS lazy loading libraries like lazysizes.js, thinking it offers more control than native loading="lazy". It's actually worse:
| Approach | Source of Delay |
|---|---|
loading="lazy" |
Skipped by preload scanner, pushed to queue tail |
| JS lazy loading | Must wait for JS download + execution before image loading begins |
JS lazy loading is double-delayed: wait for the script, then wait for the image.
The Right Approach in 2026
One core principle: only use lazy loading for content below the fold.
Above the fold (viewport)
├── LCP element (hero image, main banner)
│ ├── No loading="lazy"
│ ├── Add fetchpriority="high"
│ └── Combine with <link rel="preload"> for early discovery
│
└── Other above-fold images
└── Leave as default (browser automatically uses eager loading)
Below the fold
└── All images → loading="lazy" ✅ This is the correct usage
fetchpriority: The Most Underrated Attribute of 2026
fetchpriority="high" is the opposite of loading="lazy". It explicitly tells the browser: "This resource is critical — prioritize it." Chrome/Edge support is already at 90%+, yet adoption remains far below where it should be.
<!-- LCP hero image: highest priority -->
<img src="hero.webp"
fetchpriority="high"
width="1200" height="600"
alt="hero">
<!-- Below-the-fold image: lazy load -->
<img src="product.webp"
loading="lazy"
width="400" height="300"
alt="product">
<!-- Optimal combination (preload + high priority) -->
<link rel="preload" as="image" href="hero.webp" fetchpriority="high">
<img src="hero.webp" fetchpriority="high" width="1200" height="600" alt="hero">
Real-world data: correctly applying fetchpriority="high" improves LCP by 100–200ms.
Framework-Specific Pitfalls
WordPress
WordPress 6.3+ automatically adds fetchpriority="high" to the first image. However, third-party optimization plugins (WP Rocket, Autoptimize, etc.) may override this behavior.
How to check: Run Lighthouse → look for the "LCP image was lazily loaded" warning.
Next.js
Next.js's <Image> component lazy loads everything by default. Hero images must include the priority prop:
// ❌ Wrong: hero image gets lazy loaded
<Image src="/hero.jpg" alt="hero" />
// ✅ Correct: priority = fetchpriority="high" + no lazy loading
<Image src="/hero.jpg" priority alt="hero" />
Global JS Lazy Loading Libraries
If you're using lazysizes.js to handle all .lazyload images uniformly, make sure to explicitly exclude your LCP element.
Target Metrics
- LCP < 2.5s = Good
- LCP 2.5–4s = Needs improvement
- LCP > 4s = Poor (direct impact on search rankings)
Delay caused by lazy loading an LCP image: typically 50–300ms+, sometimes exceeding 1 second in severe cases.
Conclusion: Layered Thinking for Image Performance
Lazy loading is a good tool. In the wrong place, it becomes a bad one.
The key is developing a layered mental model: what's in the viewport should load fast; only defer what's outside it. Use fetchpriority="high" to tell the browser what matters most, and loading="lazy" to tell it what can wait.
No plugins. No libraries. Just a few HTML attributes — and your LCP score can move from red to green.
Data sources: 2025 Web Almanac, Chrome DevTools measurements, corewebvitals.io
Top comments (0)