
Lazy loading is supposed to make pages faster. You defer off-screen images until the user scrolls toward them, the browser downloads less upfront, and everyone wins. That is the theory. In practice, a large share of WordPress lazy-loading setups actively hurt performance, and the culprit is almost always a plugin doing too much, doing it the old way, or doing it to the wrong images. Here is exactly where they go wrong and how to fix each problem.
This is the single most damaging thing a lazy-loading plugin can do, and it is shockingly common. Your hero image, the first product photo, the featured image at the top of a post: these are usually your Largest Contentful Paint element. When a plugin slaps loading="lazy" on that image, the browser deprioritizes it, often waiting until layout is computed before it even begins the download. The result is a measurably slower LCP, the exact opposite of what you wanted.
You want LCP under 2.5 seconds. Lazy-loading the above-the-fold image routinely pushes it past that. The correct treatment for the hero image is the opposite of lazy: it should be eagerly loaded and marked fetchpriority="high" so the browser fetches it first.
WordPress core actually gets this right out of the box. Since WordPress 5.9, core skips lazy loading on the first content image, and since WordPress 6.3, core automatically adds fetchpriority="high" to the image it identifies as the likely LCP element. The problem is that aggressive plugins override this. If your plugin "lazy loads all images" with no above-the-fold exclusion, it is undoing core's careful work. Look for a setting like "exclude first N images" or "DOM-based above-the-fold exclusion" (Perfmatters and WP Rocket both offer this) and make sure your hero is excluded.
Native browser lazy loading via the loading="lazy" attribute has been supported across all current browsers for years, and WordPress core has emitted it automatically since WordPress 5.5 (August 2020). It costs zero JavaScript and zero render-blocking overhead.
Yet plenty of plugins still ship a lazysizes-style JavaScript library that replaces src with data-src, waits for scroll events, and swaps the real source in at runtime. In 2026 this is mostly redundant weight. It adds a script to parse and execute, it depends on JavaScript succeeding, and it can leave broken images for crawlers and users on flaky connections. Older plugins like a3 Lazy Load were built around this JS-first model.
The fix: prefer native lazy loading. If a plugin offers a choice, pick the native attribute over the JS engine. The legitimate exceptions are background images set via CSS and video/iframe embeds, which native loading="lazy" does not fully cover and where a small script genuinely adds value.
When an image loads late and you have not told the browser how tall it will be, surrounding content jumps as the image pops in. That is Cumulative Layout Shift, and you want it under 0.1. Lazy loading makes CLS worse precisely because the image arrives after the user is already reading.
The fix is to always emit explicit width and height attributes (or a CSS aspect-ratio) so the browser reserves the exact space before the file downloads. WordPress core adds width and height to content images automatically, but page builders and some galleries strip or omit them, especially for background and CSS-driven images. If your lazy-loaded images cause shift, the lazy loading is not the disease, the missing dimensions are. Audit the actual rendered HTML rather than trusting the plugin's checkbox.
"Lazy load all images" sounds thorough. It is actually crude. A good lazy-loading strategy excludes:
Plugins that expose only an on/off switch with no exclusion rules push you toward the wrong default. Tools like WP Rocket, Perfmatters, and LiteSpeed Cache let you exclude images by class, by URL pattern, or by count from the top of the page. Use those rules. A blanket "lazy everything" toggle is a sign the plugin was built for marketing screenshots, not Core Web Vitals.
Because core now emits loading="lazy" on its own, a plugin that also processes the same images can stack two mechanisms on top of each other: the native attribute plus a JavaScript swap. Symptoms include images that never load until you scroll twice, placeholder flicker, broken images on the first paint, and conflicts where the plugin's data-src rewrite fights core's attribute.
If you run a dedicated lazy-loading plugin or a caching plugin's lazy-load module, you usually want exactly one system in charge. Many performance plugins ship a "disable WordPress core lazy load" option specifically so their engine does not collide with core's. Check that you have not accidentally enabled lazy loading in two places at once, for example in both Jetpack and a caching plugin.
LQIP (Low Quality Image Placeholder) and blur-up effects look slick: a blurred thumbnail fades into the sharp image. But many implementations inline a base64 placeholder into the HTML for every image, inflating the document size, and drive the transition with extra JavaScript. For a gallery-heavy page you can add tens of kilobytes of placeholder data to your initial HTML payload, which is the one thing you most want to keep lean.
Optimole and Smush both offer LQIP-style effects. They can be worthwhile on image-rich, design-led sites, but treat them as a deliberate aesthetic choice, not a free performance win. If you are chasing a passing Core Web Vitals score, a plain reserved-space placeholder beats an animated blur almost every time.
srcJavaScript-based lazy loading that hides the real image behind data-src can leave images invisible to tools that do not execute JavaScript fully, which matters for image search indexing and for social and link-preview scrapers reading your Open Graph image. Native loading="lazy" keeps a real src in the markup and sidesteps the issue entirely. If you must use JS lazy loading, make sure your most important images, your OG image, and anything you want in Google Images are excluded or have a discoverable source.
Put together, the practical setup looks like this:
fetchpriority to the LCP candidate.Lazy loading is a precision tool, not a switch you flip to "on." The plugins that get it wrong treat every image identically and bolt on JavaScript the browser no longer needs. The ones worth using give you exclusion rules, respect core's defaults, and stay out of the way of your most important image.
Site
Tools
We do not sell your email. We do not spam.
© 2026 RevealTheme. All rights reserved.