Web Speed

Why Lazy Loading Made Your Site Feel Slower

Lazy loading images is genuinely good advice that gets applied genuinely badly. The idea: don’t load images the visitor can’t see yet. The common implementation: don’t load images the visitor is currently looking at either. That’s how a performance feature turns a site sluggish, and why your PageSpeed score dropped after you "optimized."

Lazy loading below the fold is optimization. Lazy loading the hero image is telling the browser to procrastinate on the one thing that matters.

Illustration of a web page loading fast, with a speed gauge, Why Lazy Loading Made Your Site Feel Slower
Lazy loading images should speed a page up, but on the hero it delays LCP.

The hero image mistake

Largest Contentful Paint, the Core Web Vitals metric Google weighs heaviest, measures when your biggest visible element finishes rendering. On most sites that’s the hero image. Lazy loading works by telling the browser "this image isn’t urgent, fetch it when you get around to it." Apply that to the hero and you’ve deprioritized the exact image LCP is timing.

The browser dutifully waits, your LCP balloons past 2.5 seconds, and the page feels slower because the main thing visibly pops in late. Google’s own research on lazy-loaded LCP images found this pattern consistently degrading performance across the web.

The reason is mechanical. Normally the browser spots image tags while it is still reading the HTML and starts downloading them straight away. A lazy image can’t start until the browser has worked out the layout and confirmed the image is near the screen. On a phone on a slow connection, that wait is long enough to see.

How it happens without you choosing it

Three common paths. WordPress adds loading="lazy" to images by default: core tries to skip the first images, but themes and builders that render heroes in unusual ways defeat the detection. Optimization plugins often apply JavaScript-based lazy loading to everything, hero included, and JS-based lazy loading is worse than the native kind: the image can’t even start until the script loads and runs. And sliders are the worst case: many load slide one lazily and inject the rest with JavaScript, making your most important visual doubly delayed.

Ready-made themes are especially prone to this, because they build heroes from generic blocks the lazy loading logic can’t recognise. It is one of the quieter arguments for a custom website over a template: every template decides what loads first, and a custom build puts that decision in your hands. Shop themes and apps do the same thing, which is part of why Shopify stores get slow too.

How to check if your hero is lazy loaded

You don’t need to guess. Two checks take a couple of minutes:

  1. Run the page through PageSpeed Insights and find the LCP element in the diagnostics. If it is an image, Lighthouse will flag it when that image was lazily loaded.
  2. Right-click the hero, choose Inspect, and read the tag. Look for loading="lazy", or for a data-src attribute and a class such as lazyload. Those last two mean a script is in charge, and the real image address isn’t in src at all.

Check on a mobile view as well as desktop. What sits above the fold changes with screen size, and the image that matters on a phone is not always the one that matters on a laptop.

Infographic summarising “Why Lazy Loading Made Your Site Feel Slower”: The hero image mistake; How it happens without you choosing it; How to check if your hero is lazy loaded; The fix: priority, not just exclusion; Where lazy loading images actually pays off; Verify the result
The article at a glance.

The fix: priority, not just exclusion

The hero image should be the opposite of lazy. Three steps:

1. Remove lazy loading from above-the-fold images

The hero, the logo, anything visible on arrival. In most optimization plugins that’s an exclusion field; in a proper theme it’s handled per-template.

2. Actively prioritize the hero

Add fetchpriority="high" to the hero image and preload it in the head. Now the browser fetches it first instead of merely not-last.

In practice the hero tag ends up looking like <img src="hero.webp" width="1600" height="900" fetchpriority="high" alt="...">, with no loading attribute at all. If the image uses srcset, make sure the preload describes the same set, or the browser may download one size for the preload and a different one for the page.

3. Keep lazy loading everywhere else

Gallery grids, footer content, long-page images. That’s where the technique belongs and where it genuinely helps.

Where lazy loading images actually pays off

Used on the right things, lazy loading saves real bandwidth and gets the first screen out faster, because the browser isn’t fetching thirty gallery photos nobody has scrolled to yet. Good candidates:

  • Image grids on portfolio, gallery and product listing pages.
  • Images deep inside long blog posts.
  • Embedded YouTube videos and maps, which accept loading="lazy" on the iframe.
  • Footer logos, badges and partner strips.

Prefer the native attribute over a JavaScript library. Every current browser supports it, it needs no extra script, and it fails safe: if anything goes wrong, the image simply loads.

Mistakes that undo the fix

  • Running native lazy loading and a plugin’s script version at the same time.
  • Lazy images with no width and height, which reserve no space and shift the layout when they arrive.
  • Preloading the hero but leaving it at a heavy size. Priority helps, but a lighter file helps more, so compress it as WebP or AVIF as well.

Verify the result

Re-run PageSpeed Insights and check the LCP element it reports. If LCP was 4+ seconds with a lazy-loaded hero, this fix alone commonly claws back one to two full seconds.

If the score’s still red afterward, the problem has more layers (image weight, render-blocking code, server response), which is the point where a full speed optimization pass earns its fee: it fixes the causes in the right order instead of stacking plugins on symptoms.

Questions people ask

Should I lazy load the hero image?

No. The hero is usually the Largest Contentful Paint element, so lazy loading it tells the browser to delay the one image Google is timing. Remove the loading attribute from the hero, add fetchpriority high, and keep lazy loading for images further down the page.

Does lazy loading hurt SEO?

Lazy loading below the fold does not hurt SEO and usually helps page speed. It hurts when it is applied to the hero or other images visible on arrival, because it slows Largest Contentful Paint, which is one of the Core Web Vitals Google uses as a ranking signal.

Is native lazy loading better than a JavaScript plugin?

In most cases, yes. The native loading attribute is supported by every current browser, needs no extra script, and still loads the image if something fails. JavaScript lazy loading cannot start until its script has downloaded and run, which adds delay, and it hides the real image address from the browser.

How do I stop WordPress lazy loading my hero image?

WordPress core already tries to skip the first images, so check where the lazy loading comes from. If an optimization plugin adds it, use its exclusion field for the hero file or class. If the theme or builder renders the hero unusually, the template needs to output the image without the loading attribute.

Comments

Leave a comment

0 / 3000
Comments are moderated. Links are not clickable and your email is never published. See the privacy policy.
keep reading

Related articles

Usually replies within a day
let’s talk

Tell me what you want to build

A website, an app, some automation, or something you’re still figuring out. Tell me the problem and I’ll give you a straight answer on what it takes. No pressure, no sales team.