Images are almost always the heaviest part of a WordPress page. On a typical content page, they account for more than half of the transferred bytes — and most of those images sit below the fold, downloaded long before the visitor ever scrolls to them. When you lazy load images in WordPress, the browser only fetches the images it needs right now and defers the rest until they approach the viewport. The result: faster initial loads, less wasted bandwidth, and better Core Web Vitals scores.
WordPress has handled lazy loading natively for years, so in many cases you don’t need a plugin at all. But the default behavior has gaps and one very common misconfiguration that can actually hurt your Largest Contentful Paint (LCP) score. This guide covers how native lazy loading works, how to verify it, when to use a plugin, and which images you should deliberately exclude.
What Lazy Loading Actually Does
Lazy loading is a loading strategy, not a compression technique. A normal <img> tag tells the browser “download this immediately.” Adding the loading="lazy" attribute tells the browser “download this only when it’s about to scroll into view.”
Browsers handle the timing themselves — Chrome starts fetching an image roughly when it’s within ~1,250 pixels of the viewport, so it finishes loading just before the visitor reaches it. If the visitor never scrolls down, those images are never downloaded at all. On image-heavy pages (long blog posts, portfolios, WooCommerce category archives) this cuts initial page weight dramatically.
There are three values for the loading attribute: lazy (defer until near the viewport), eager (load immediately, the default behavior), and auto (let the browser decide).
How WordPress Lazy Loads Images by Default
Since WordPress 5.5, core automatically adds loading="lazy" to images that have explicit width and height attributes. This covers images inserted through the block editor, featured images, galleries, and images in widgets and comments. There’s no setting to turn on and no JavaScript overhead — the browser does the work natively.
WordPress 5.7 extended the same treatment to iframes, so YouTube embeds and Google Maps iframes also lazy load by default.
WordPress 6.3 added the other half of the equation: automatic fetchpriority="high" on the image most likely to be the LCP element. This is the reverse of lazy loading — it tells the browser to prioritize the hero image download even before layout is computed, which the WordPress performance team estimated could improve LCP by 5–10% (proposal details). The two attributes are mutually exclusive: an image gets one or the other, never both (Search Engine Journal on WP 6.3).
In practice, this means a default WordPress install in 2026 already lazy loads your content images correctly. So why do so many sites still get flagged for image loading issues? Because of what native lazy loading doesn’t cover.
Step 1: Verify Native Lazy Loading Is Working
Before adding anything, check what WordPress is already doing on your site:
- Open any page with several images in Chrome.
- Right-click an image below the fold and choose Inspect.
- Look at the
<img>tag — you should seeloading="lazy"in the markup.
If you don’t see it, the likely causes are an outdated theme that hard-codes <img> tags without loading attributes, images added via custom fields or raw HTML, or a plugin that disables it (add_filter('wp_lazy_loading_enabled', '__return_false') somewhere in your stack). Update first, investigate second.
Then run the page through PageSpeed Insights and look at the Diagnostics section. If you see “Defer offscreen images” or “Largest Contentful Paint image was lazily loaded”, you have a real problem to fix — the latter one is the expensive mistake covered below.
Step 2: Know What Native Lazy Loading Misses
WordPress’s built-in lazy loading only applies to <img> and <iframe> tags it renders. It does not cover:
- CSS background images. The
loadingattribute doesn’t exist for backgrounds — there’s no HTML tag for the browser to defer. Hero sections built with background images are one of the most common LCP bottlenecks I see on client sites. - Video embeds beyond the iframe. WordPress adds
loading="lazy"to YouTube iframes, but the embed still pulls in multiple scripts, preview images, and tracking code early. For video-heavy pages, a “facade” approach — showing a lightweight thumbnail and loading the real player only on click — saves far more than iframe lazy loading alone. - Images output by custom theme code. Sliders, carousels, and custom Gutenberg blocks that echo raw
<img>tags often lack the attribute entirely. Audit your theme’s templates and addloading="lazy"plusdecoding="async"to any below-the-fold image markup.
If your audit turns up gaps like these, a performance plugin fills them more reliably than hand-editing templates.
Step 3: Use a Plugin for Full Control (LiteSpeed Cache Example)
You don’t need a lazy loading plugin just for content images — WordPress already handles those. Where plugins earn their place is everything else: background images, iframes, above-the-fold exclusions, and videos. My usual recommendation is the cache plugin you’re already running, since adding a separate lazy-load plugin on top of another optimizer causes conflicts.
In LiteSpeed Cache (what I use on most client sites):
- Go to LiteSpeed Cache → Page Optimization → Media Settings.
- Enable Lazy Load Images — this covers images, background images (via its own JS), and iframes that core misses.
- Open the Exclude Above the Fold setting and add the number of above-the-fold images to skip (start with 3 and verify with PageSpeed Insights). This is the critical setting — see the next section for why.
- If you use YouTube embeds, enable Lazy Load YouTube/Vimeo Iframes to replace them with clickable thumbnails.
Similar controls exist in WP Rocket (LazyLoad tab), Perfmatters, and FlyingPress. The principle is identical everywhere: lazy load everything below the fold, exclude everything above it. If you want a deeper plugin comparison, see my earlier roundup of cache plugins — and for the server-side half of performance, read my guide on reducing server response time in WordPress.
The #1 Mistake: Lazy Loading Above-the-Fold Images
This is the single most damaging lazy loading error, and I see it constantly: the hero or LCP image gets loading="lazy", which delays the most important image on the page. PageSpeed Insights flags this explicitly as “Largest Contentful Paint image was lazily loaded,” and it can add hundreds of milliseconds to LCP.
Never lazy load:
– Your hero/banner image
– The site logo (if rendered as an image in the viewport)
– Any image visible without scrolling on first load
– The featured product image on a WooCommerce product page
Do this instead for your LCP image:
<img src="hero.webp"
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
width="1200" height="630"
alt="Describe the image"
loading="eager"
fetchpriority="high">
One rule of thumb: only one fetchpriority="high" per page. Setting it on multiple images dilutes the signal and you’re back where you started.
If you’re working with a child theme, you can programmatically exclude specific images from lazy loading — for example, anything with a no-lazy class:
// Exclude images with the "no-lazy" class from native lazy loading
add_filter( 'wp_img_tag_add_loading_attr', function( $value, $image, $context ) {
if ( false !== strpos( $image, 'no-lazy' ) ) {
return false;
}
return $value;
}, 10, 3 );
For more on diagnosing interaction delays after your images are sorted, see my guide on improving INP in WordPress.
Lazy Loading Checklist
Run through this on every site you optimize:
- Update WordPress and your theme — native lazy loading and
fetchpriorityonly exist in recent versions. - Inspect below-the-fold images — confirm
loading="lazy"is present. - Inspect above-the-fold images — confirm
loading="lazy"is absent and the LCP image hasfetchpriority="high". - Audit background images — convert critical ones to real
<img>tags or handle them in your cache plugin. - Check video embeds — use click-to-play facades on video-heavy pages.
- Re-test in PageSpeed Insights – “Defer offscreen images” and “LCP image was lazily loaded” should both be gone.
Lazy loading is one of the highest-ROI optimizations in WordPress precisely because it’s mostly automatic — your job is verifying the defaults, covering the gaps, and above all keeping it off your hero image. Get those three things right and your image payload stops working against your Core Web Vitals.
Want your WordPress site audited for speed? I specialize in Core Web Vitals and PageSpeed optimization — get in touch and I’ll find what’s actually slowing your site down.