WordPress Lazy Load: What It Does, What It Breaks, and How to Set It Up Properly
Lazy loading is one of those settings that looks like a straightforward win. Switch it on, images load only when needed, page feels faster. The problem is that applied carelessly it actively harms your Core Web Vitals score, specifically your Largest Contentful Paint. Most sites have it misconfigured. This guide walks through what lazy loading actually does, where it goes wrong, and how to set it up so it helps rather than hurts.
On this page
What Lazy Loading Does Under the Bonnet
The browser-native approach uses a single HTML attribute: loading='lazy' added directly to an <img> tag. The browser then defers fetching that image until it is close to entering the viewport. No JavaScript, no extra library, just a hint the browser chooses how to honour.
JavaScript-based lazy loading is older and works differently. A script watches scroll position and swaps a placeholder src for the real image URL once the element is near the screen. It works, but it adds execution overhead, and on slower connections the image swap can produce a visible flicker or a layout jump if dimensions are not set properly.
Modern WordPress uses the native attribute by default for images below the fold. Some performance plugins layer their own JavaScript solution on top of that, which can create conflicts or double-defer images that should load immediately. Before you touch any settings, it is worth knowing which method your site is actually using.
The LCP Trap
This is where things go wrong fast. Apply lazy loading to your hero image and you have told the browser to wait before fetching the single most important visual on the page. Google measures Largest Contentful Paint, the time it takes for the biggest visible element to render, and a lazily loaded hero image pushes that number up sharply.
A common issue we see is a site passing every other performance check but failing LCP purely because a well-meaning plugin has added loading='lazy' to the banner image at the top of every page. The fix takes thirty seconds once you know it is there. Finding it in the first place takes longer.
How to Spot Your LCP Element
Run the page through PageSpeed Insights and scroll to the Diagnostics section. It will name the LCP element directly, often with a thumbnail. If it is an image, check its source code for loading='lazy' or data-src attributes, which signal JavaScript-based deferral. Either one on your LCP image needs fixing immediately.
Choosing Where to Apply It
Not every image on a page is equal. The decision really comes down to one question, is this image visible without scrolling on a typical screen?
Content That Benefits from Lazy Loading
- Image galleries, particularly on portfolio or product pages with ten or more images
- Long-form blog posts where images sit deep in the article
- Footer sections carrying partner logos, embedded maps, or social feeds
- YouTube embeds and other iframes that are not visible on page load
Always Exclude These
- Hero images and any image in the first viewport on desktop and mobile
- The logo in your header
- Above-the-fold product images on e-commerce pages
- Any image your PageSpeed report identifies as the LCP element
Auditing your own pages takes ten minutes. Open Chrome, resize the browser to a typical mobile width (around 390px), and scroll to the fold. Every image visible at that point should load eagerly. Everything below it is a candidate for deferral. For practical advice on formats and file sizes alongside this, image optimisation for WordPress covers the broader picture.
Setting It Up Without Breaking Anything
Most WordPress performance plugins handle lazy loading through a dedicated toggle, often under a Media or Images tab. WP Rocket, for example, separates image lazy loading from iframe lazy loading, which is useful because you may want to defer YouTube embeds while leaving images on their default behaviour.
Set Your Exclusions First
Before enabling anything, set your exclusions. Most plugins accept CSS class names or partial filename strings. Add the CSS class your theme applies to hero images, usually something like .hero-image, .wp-post-image, or a builder-specific class. If you are unsure, inspect the element in Chrome DevTools and copy the class directly from the markup.
For iframes, exclude any map embed that sits above the fold. Google Maps iframes are heavy and deferring them makes sense when they are buried in a footer, but not when they appear midway up a short contact page where the map is visible on arrival.
One setting to double-check is whether the plugin adds loading='lazy' to images that WordPress has already marked with fetchpriority='high'. That attribute is how WordPress signals the LCP image to the browser, and a plugin that overrides it with lazy loading is undoing that work automatically and silently. It is an easy thing to miss.
Testing Once It’s Live
Run PageSpeed Insights again after making changes. Look at the LCP score and the screenshot filmstrip. If the hero renders early in the filmstrip, you are in good shape. If it appears late, lazy loading is still interfering somewhere.
In Chrome DevTools, open the Network tab, filter by Img, and reload the page. Images that load immediately appear at the top of the waterfall. Lazy-loaded images appear later as you scroll. Confirm your hero image is in that first group.
Also check for layout shift. If images do not have explicit width and height attributes set in the HTML, the browser cannot reserve space for them before they load. That causes content to jump as images appear, which hurts Cumulative Layout Shift. Add dimensions to any image that lacks them, particularly below-fold gallery images. For a deeper look at exactly how lazy loading affects paint timing, this breakdown of lazy loading behaviour covers the timing mechanics in detail.
If lazy loading is configured correctly, pages load faster and nobody notices the images arriving in stages. If something is wrong, the LCP number will tell you exactly where to look.