Why Images Are Usually the Heaviest Part of a Page
On most WordPress sites, images account for more of the page weight than the theme, the plugins, and the stylesheets combined. That is not a criticism of images — a product photo, a tutorial screenshot, or a portfolio shot often does more work than a paragraph ever could. The problem is timing. By default, a browser tries to download every image on a page as soon as it starts loading, including the ones a visitor will never scroll down to see.
Lazy loading fixes that timing problem. Instead of loading every image up front, the browser loads only the images near the top of the page, then fetches the rest as the visitor scrolls toward them. The page becomes usable sooner, less data is transferred on the first visit, and visitors on slow connections or mobile data plans get a noticeably faster experience. Done well, it is one of the simplest speed wins available in WordPress. Done carelessly, it can make your largest image slower, not faster — which is why the details in this guide matter.
What Lazy Loading Actually Does
Think of a long article with twenty images. Without lazy loading, the browser queues all twenty downloads before the visitor has read a single sentence. The network gets crowded, the main thread gets busy decoding images, and the content the visitor actually came for has to compete for bandwidth.
With lazy loading, the browser loads the images in and near the visible area first, and holds the rest back until they are about to enter the viewport. Images further down the page are not skipped — they are simply deferred. By the time a reader scrolls to them, they are usually already loading or loaded. The total amount of data is the same for someone who reads the whole page; the difference is that none of it blocks the first impression.
This is also why lazy loading pairs so well with good image preparation. Lazy loading changes when an image loads, not how big it is. If you want the full benefit, start by making sure your images are sensibly sized and compressed — our guide to compressing images for WordPress without losing quality covers the settings that look fine in practice — and consider a modern format, as compared in WebP vs AVIF for WordPress. A lazy-loaded image that is still three megabytes is still a three-megabyte problem, just a later one.
What WordPress Already Does for You
If your site runs a reasonably current version of WordPress, you already have native lazy loading, and you may not need a plugin at all. WordPress automatically adds loading="lazy" to images in post content, and since WordPress 5.9 it has also applied the attribute to images in the block editor and in many widgets. It is deliberately conservative: WordPress does not lazy load the first image in your content, because that image is often the one visitors see first.
That default covers the common case well. If your site is a standard blog or business site built with the block editor, with images added through normal image blocks, native lazy loading is probably already working. You can verify it in seconds: open any post, right-click an image below the fold, inspect it in your browser, and look for loading="lazy" in the markup. If it is there, the mechanism is in place and the rest of this guide is about getting the edges right.
Where native lazy loading falls short is everything outside standard post content: images loaded by page builders, sliders, galleries, theme headers, widgets, and custom templates. Some of those handle lazy loading themselves, some do not, and some do it in ways that conflict with WordPress. That gap — not a missing plugin — is usually where a site’s lazy loading setup needs attention.
The One Rule That Matters Most: Never Lazy Load the Hero Image
There is a single mistake behind most lazy loading horror stories, and it is this: lazy loading the image at the top of the page. Your hero image, featured image, or logo is usually your Largest Contentful Paint (LCP) element — the largest visible element the browser paints, and therefore the one that determines a large part of your LCP score. If that image is lazy loaded, the browser deliberately delays it, and your LCP gets worse instead of better.
The rule is simple: any image visible without scrolling should load eagerly, with high priority. In practice that means the hero or featured image gets loading="eager" and, ideally, fetchpriority="high". Everything below the fold gets loading="lazy". If you only remember one sentence from this guide, make it that one. We have a separate, detailed walkthrough for the case where this has already gone wrong: how to fix the “LCP image was lazily loaded” warning in WordPress.
This rule also applies to images that are technically below the fold on a desktop screen but visible on a phone, and vice versa. Test on both. A banner that sits below a long desktop navigation menu may be the first thing a mobile visitor sees. When in doubt, load it eagerly — the cost of loading one extra image early is far smaller than the cost of delaying your LCP element.
Method 1: Rely on Native Lazy Loading (and Fix the Gaps)
For most sites, the best approach is to keep native lazy loading and fix only the specific gaps. Start by confirming what is already lazy loaded, using the inspect method above, on a post, a page, and your homepage. Then check the places WordPress does not cover.
If your theme loads a featured image at the top of single posts, make sure it is not being lazy loaded by the theme or by a plugin. The same goes for a logo or a header banner image. If you find loading="lazy" on any of those, remove it — either through your theme’s settings, by editing the template, or by asking your theme developer where the attribute is added. Do not add a lazy loading plugin on top of a theme that already lazy loads its own images; two systems fighting over the same attribute is a common source of broken placeholders and layout shift.
For images in custom HTML blocks or shortcodes, you can add the attribute by hand:
<img src="photo.jpg" alt="A descriptive alt text" loading="lazy" width="800" height="600">
Notice the width and height attributes. They are not decoration. Without them, the browser does not know how much space to reserve for an image that has not loaded yet, so content jumps down the page when the image finally appears. That jump is Cumulative Layout Shift (CLS), and lazy loading without dimensions is one of the easiest ways to cause it. Always include dimensions, or use CSS aspect-ratio, for every lazy-loaded image.
Method 2: Use a Plugin When You Need More Control
A plugin makes sense when native lazy loading does not reach your images, or when you want features native loading does not provide — a low-quality placeholder, a fade-in effect, or lazy loading for background images and iframes. Most reputable caching and optimization plugins include lazy loading as one option among many, and that is usually the cleanest route: if you already run a caching plugin, check whether it has a lazy loading toggle before installing a dedicated plugin.
Whichever plugin you choose, configure it with the same principles. First, find its exclusion setting and add your hero image, logo, and any above-the-fold image to it — most plugins let you exclude by filename, CSS class, or URL. Second, enable it for images only at first, and test before turning on background-image or iframe lazy loading, which are more likely to break layouts. Third, do not run two lazy loading systems at once. If your caching plugin lazy loads images and your theme does too, disable one of them and test again.
A dedicated lazy loading plugin is also worth considering for page-builder sites, where images are often rendered through builder widgets rather than standard blocks. In that case, check the builder’s own documentation first: many builders have a native lazy loading or “load on scroll” setting, and enabling both the builder’s setting and a plugin’s setting can double up in unhelpful ways. One system, configured carefully, beats two systems every time.
What About Background Images?
Background images set in CSS do not support the loading attribute, because there is no image element for the browser to defer. Some optimization plugins handle them with JavaScript, swapping a placeholder for the real background as it approaches the viewport. That can work, but treat it as optional polish, not a core fix. A large CSS background on a hero section should not be lazy loaded at all — it is above the fold — and background images further down the page are usually a smaller part of the total weight than content images. If a plugin’s background-image option causes flicker or a flash of unstyled content, turn it off and move on.
Lazy Loading on Mobile: Where It Pays Off Most
Mobile visitors benefit from lazy loading more than anyone, for two reasons: their connections are often slower, and their screens show fewer images at once, so a larger share of a page’s images sit below the fold. On a long mobile article, lazy loading can cut the initial download dramatically. It also interacts with several other mobile-specific issues — responsive image sizes, slider behaviour, and tap-target layout — which is why it is worth reading alongside our guide to speeding up WordPress on mobile without breaking your theme.
Two mobile checks are worth making specifically. First, confirm that your responsive images are actually responsive: an image that serves a 2000-pixel-wide file to a 390-pixel-wide phone screen wastes most of the benefit of lazy loading. WordPress normally handles this with srcset, but page builders and custom templates sometimes bypass it. Second, check sliders and carousels on a real phone. Many sliders preload several slides ahead, which can quietly defeat lazy loading, and some load every slide image up front regardless of settings. If a slider is your biggest mobile weight, reducing the number of slides or switching to a static image may help more than any lazy loading tweak.
How to Test That Lazy Loading Is Working
Testing lazy loading properly takes about five minutes, and it is worth doing after any change. Start with the browser check described earlier: inspect images on a post and confirm that below-fold images carry loading="lazy" and above-fold images do not. Then open your browser’s developer tools, go to the Network tab, filter by images, and reload the page without scrolling. You should see only the above-fold images load. Scroll down slowly, and watch the remaining images appear in the network log as they approach the viewport. If every image loads on the initial reload, lazy loading is not active for those images — check whether a plugin, theme, or page builder is overriding it.
Next, run a PageSpeed Insights test and look at two things: the LCP element, which should not be a lazy-loaded image, and any diagnostics about offscreen images. A warning about offscreen images means some below-fold images are still loading eagerly — the opposite problem, and usually a sign that a particular template or widget is not covered by your lazy loading setup. Finally, test on a throttled connection or a real phone, because lazy loading behaviour on a fast desktop connection can hide problems that are obvious on a slow mobile connection.
Common Mistakes (and How to Avoid Them)
The hero-image mistake is the biggest, but it is not the only one. Lazy loading images inside a tab, accordion, or slider that is hidden on load can cause those images to load late or not at all when the section is opened, because the browser may never consider a hidden element to be near the viewport. If images inside interactive elements appear broken or slow, exclude them from lazy loading first and see if the problem clears.
Another common mistake is lazy loading every image on a short page. If a page has only three images and all of them are visible or nearly visible, lazy loading saves almost nothing and adds a small delay to each image. Lazy loading earns its keep on long pages with many images. On short pages, it is harmless but pointless — do not chase it as a score improvement there.
Finally, watch for layout shift. If content jumps as images load, the cause is almost always missing dimensions, not lazy loading itself. Add width and height attributes, reserve space with CSS aspect-ratio where dimensions vary, and avoid changing an image’s displayed size after it loads. A page that loads fast but jumps around as you read it is not a fast page in any sense that matters to a visitor.
A Sensible Lazy Loading Checklist
To wrap up, here is the setup this guide recommends for most WordPress sites. Keep native lazy loading on, or use one plugin if native loading does not reach your images. Load your hero, logo, and every above-fold image eagerly, with high fetch priority where it helps. Lazy load everything below the fold, with width and height set on every image. Exclude images inside sliders, tabs, and accordions if they misbehave. Compress and resize images before worrying about loading order. Then verify with the Network tab and PageSpeed Insights, on desktop and on a real phone.
Lazy loading is not a magic fix, and it will not rescue a page full of uncompressed, oversized images. But as part of a sensible image workflow — right-sized files, modern formats, correct dimensions, and sensible loading order — it is one of the highest-return changes you can make, and one of the few that costs nothing and risks almost nothing when the hero-image rule is respected.