TL;DR
WordPress has automatically lazy-loaded images since version 5.5—but applying it to the wrong images, like your hero or logo, can actively hurt your LCP score and trigger PageSpeed Insights warnings. The fix is making sure above-the-fold content is excluded, your videos use facades, and your setup is actually verified. Tools like NitroPack handle all of this automatically, but this guide walks you through every option so you can choose what works best for your site.
WordPress lazy loading defers the loading of images and iframes until they approach the viewport. Since WordPress 5.5, this happens automatically for elements with defined width and height attributes—so there’s a good chance it’s already active on your site without you doing a thing.
And while lazy loading is a crucial part of website optimization, it’s not supposed to be a shotgun approach that you apply to every image. This can actually hurt your performance if applied poorly.
Specifically, if you lazy-load above-the-fold content, like your hero image or logo. This will get you warnings on your Google Page Speed Insights tests, but it can also have an impact on how Google ranks you on SERPs, too.
There’s no need to worry, however.
This guide will help you verify your current setup and show you a way to completely automate the process. Because who wants to add lazy loading attributes to every image? Let’s get started.
Test your website with NitroPack
What is lazy loading in WordPress?
When someone visits your site, the browser doesn’t have to load every single image on the page at once. Lazy loading tells it: “Only load what the user can actually see right now. Everything else can wait.”
Images below the fold—the part of the page you have to scroll to reach—stay in a placeholder state until the user scrolls near them. At that point, the browser fetches and displays them. It’s a simple idea with a real impact on how fast your pages feel.
That’s because deferring offscreen images reduces the amount of data a browser needs to process on the initial load, which directly shrinks your page weight and speeds up that first render. Just what you want when optimizing images.
In practical terms, lazy loading connects to two PageSpeed Insights warnings you may have seen before:
- “Defer offscreen images”: Your below-the-fold images are loading upfront when they don’t need to.
- “LCP request discovery”: Your most important above-the-fold image is being incorrectly deferred.
The first warning means you need more lazy loading. The second means you have too much of it in the wrong place. Both are fixable, and we’ll cover exactly how.
3 methods to enable image lazy loading in WordPress
There’s no single “right” way to set up lazy loading in WordPress—it depends on how much control you need and how hands-on you want to be. The three main options are native WordPress support, a plugin, or manual code. Let’s start with what’s already running on your site.
1. Native lazy loading
Since WordPress 5.5, lazy loading is built in. WordPress automatically adds the loading="lazy" attribute to any image or iframe that has defined width and height attributes—no plugin, no code, no setup required.
WordPress 5.9 went a step further, attempting to skip lazy loading for the first featured image on a page to protect LCP. In theory, that sounds like enough. In practice, it often isn’t.
That’s because WordPress doesn’t actually “see” your page the way a visitor does. It counts image positions in the HTML, not what’s visually prominent on screen. So if your layout starts with a small logo before a large hero image, WordPress may still lazily load that hero—exactly the element that determines your LCP score. CSS background images don’t get the treatment at all.
Regardless, you can quickly check whether native lazy loading is active on your site:
- Right-click any image on your page.
- Select Inspect.
- Look for
loading="lazy"in the HTML.
The bottom line:
Native lazy loading is a solid starting point for simple sites with straightforward layouts. But if your site has a hero section, a prominent logo, or any above-the-fold imagery that varies between mobile and desktop, you’ll likely need more control than WordPress core can offer.
2. Lazy loading plugin (recommended)
If native lazy loading is the “good enough” option, plugins are where you get actual control. They let you decide which images get deferred, handle content types WordPress core ignores, and—most importantly—make sure your above-the-fold visuals are never caught in the lazy loading net.
There are quite a few lazy-loading plugins to choose from, so the right pick depends on what your site needs.
| Plugin | Best for | Cost |
| NitroPack | Smart lazy loading automation + exclusions; image optimization + CDN | Paid (free plan available) |
| WP Rocket | Granular control, exclusions, video facades | Paid |
| Perfmatters | Fine-tuned exclusions and threshold control | Paid |
| Smush | Image optimization with basic lazy loading | Free/Pro |
| a3 Lazy Load | Simple, no-frills lazy loading | Free |
The NitroPack approach sits in a different category from most plugins on that list.
Rather than giving you a set of toggles to configure yourself, it handles the whole process automatically: Lazy loading kicks in alongside WebP conversion, compression, adaptive image sizing, and global CDN delivery, all without manual setup.
Critically, it automatically identifies and excludes above-the-fold elements so your LCP image loads immediately, without you having to figure out which CSS class to target.
Setting it up takes about three minutes:
- Install the NitroPack plugin from your WordPress dashboard.
- Connect your site to your NitroPack account.
- Select an optimization mode (Ludicrous gives you the most aggressive optimization).
- Done—NitroPack handles the rest from the cloud.
Just keep in mind that while NitroPack handles inline background images, it won’t catch backgrounds defined in external CSS files. It also offers less manual threshold tuning than some dedicated lazy loading plugins like Perfmatters, so if you need pixel-perfect control over when images start loading relative to the viewport, it might be a little restrictive.
That said, for most site owners who want results without the configuration rabbit hole, the automation is the point.
“The Nitro Pack Plugin dramatically improved my website page load speed time. It is easy to implement, and the support team [is] very helpful. In fact, I work in digital marketing and am in contact with many SAAS software support teams, and the Nitro Pack support team [stands] out as being the most attentive and helpful team I have [dealt] with.”—@Paul Murphy Trustpilot
Over 250,000 sites use NitroPack to handle all of that automatically, combining lazy loading with image compression, WebP conversion, and a built-in global CDN in a single setup that takes about three minutes. It’s an all-in-one website optimization plugin that can see you go green on Google PageSpeed Insights.
The free plan requires no credit card—so if you want to see what a fully optimized lazy loading setup looks like on your own site, it’s a low-risk place to start.
If you have another tool installed, the most important thing to check is that your above-the-fold images are excluded from lazy loading. We’ll cover that in a later section, so stick with us!
See NitroPack in action
NitroPack lazy loading test
The best way to confirm lazy loading is actually working—and working correctly—is to check your page source for NitroPack’s fingerprint. Any image NitroPack has lazy loaded will have its src attribute replaced with nitro-lazy-src. So instead of:
<img src="example.jpg">
You’ll see:
<img nitro-lazy-src="example.jpg">
After enabling lazy loading, it’s also worth running a before-and-after check in Google PageSpeed Insights. There are two specific warnings to watch for:
- “Defer offscreen images”—should disappear once lazy loading is correctly applied.
- “LCP request discovery”—should be gone if NitroPack’s above-the-fold exclusions are working.
If that second warning is still showing up after optimization, it’s a sign that your LCP element needs to be manually added to NitroPack’s exclusion list. You can do that under NitroPack Dashboard > Cache Settings > Images & Media > Images Lazy Loading > Exclude CSS selectors.
Plus, you can always use Test Mode to preview optimizations on your live site before they go public—useful for catching any conflicts before your visitors do.
3. Manual lazy loading (advanced)
For developers who want code-level control, WordPress provides a handful of filters to manage lazy loading behavior without touching a plugin.
The most useful ones:
wp_lazy_loading_enabled: Disable lazy loading entirely for specific contexts or content types.wp_img_tag_add_loading_optimization_attrs: Adds optimization attributes to an img HTML tag.wp_omit_loading_attr_threshold: Gets the threshold for how many of the first content media elements to not lazy-load.
These are handy for template-specific exemptions—for example, disabling lazy loading on a particular page type or excluding featured images across the board.
⚠️ Important
This approach creates a maintenance burden. Every WordPress update is a potential conflict point, and debugging code-level lazy loading across different themes and plugins adds up quickly. For most sites, a plugin handles this more reliably with far less upkeep.
Protect your LCP score by excluding above-the-fold content
LCP, or Largest Contentful Paint, measures how long it takes for the biggest visible element on your page to load. It’s one of the important metrics shown in Core Web Vitals reports, alongside CLS (Cumulative Layout Shift) and INP (Interaction to Next Paint).
For most sites, that’s a hero image, a large featured photo, or a banner. If that element gets lazily loaded, the browser intentionally delays it—which is the exact opposite of what you want.
The result is a PageSpeed Insights warning that reads: “LCP request discovery”
The first step is identifying your LCP element. The PageSpeed Insights filmstrip view shows you frame-by-frame how your page loads, making it easy to spot what’s rendering late when it shouldn’t be. Once you know what it is, you have a few ways to protect it:
- Plugin exclusions: Exclude images by CSS class, URL pattern, or by skipping the first N images on the page
- WordPress filters:
wp_omit_loading_attr_thresholdoffers a code-based approach for developers - NitroPack’s automatic detection: The LCP Preload feature identifies above-the-fold elements automatically, ensuring they load immediately, while Adaptive Image Sizing prevents layout shifts by reserving the correct space before the image arrives
That last point matters because your LCP element isn’t always the same on mobile and desktop. Automatic detection accounts for that. Manual exclusions often don’t.
Lazy load YouTube, Vimeo, and iframes
Images get all the attention when it comes to lazy loading, but it’s also perfect for video optimization, too. After all, embedded videos are often the bigger culprit behind slow pages.
When you embed a YouTube or Vimeo video, the browser loads the full player—including all its scripts, stylesheets, and tracking code—when the page opens. Even if the video is halfway down the page. Visitors don’t even need to scroll down or click play, as it’s already loaded.
That’s a significant chunk of JavaScript executing for no reason, and it shows up directly in your Total Blocking Time (TBT) score.
The fix is something called a video facade. Instead of loading the real player on page load, the browser displays a lightweight thumbnail image in its place. The actual player only loads when the user clicks to watch. The page feels faster, TBT drops, and your visitors get the same experience without the unnecessary upfront cost.
NitroPack applies video facades automatically for YouTube, Vimeo, and Wistia embeds, alongside native loading=”lazy” for iframes.
The same principle extends to Google Maps and social media embeds—anything that pulls in heavy third-party scripts benefits from being deferred until the user actually interacts with it.
Troubleshooting common lazy loading issues
Lazy loading is straightforward when everything works. When it doesn’t, the culprit is usually one of a handful of recurring issues:
- Duplicate lazy loaders: If your theme, an image optimization plugin, and a performance plugin are all applying lazy loading simultaneously, they’ll conflict—often causing images to not load at all, or to flicker on scroll. If you’re using NitroPack, disable lazy loading in any other plugins you have installed. NitroPack’s documentation covers exactly how to do this for Smush, Jetpack, Optimole, and a3 Lazy Load.
- Missing width and height attributes: Without defined dimensions, the browser can’t reserve space for an image before it loads, which causes the layout to shift as images pop in. This is what drives up your CLS score. Make sure every image on your site has explicit width and height attributes set.
- JavaScript errors can silently break lazy loading. If a script error fires before the lazy loading logic runs, images may just… never load. Open your browser’s developer console and check for any red errors on page load.
With that done, we’ll also answer some common questions around lazy loading.
- Will lazy loading break my site’s layout? Not if images have defined dimensions. NitroPack’s Adaptive Image Sizing adds these automatically, which prevents layout shifts entirely.
- Does lazy loading work for CSS background images? Only partially. Native lazy loading doesn’t apply to CSS backgrounds at all. NitroPack handles inline background images but not those defined in external CSS files—for those, you’ll need manual intervention or a plugin that supports CSS selector-based lazy loading.
- How does lazy loading affect SEO? Native browser lazy loading is completely crawler-friendly—Googlebot handles it without issues. JavaScript-only implementations need more care; if you’re relying on JS-based lazy loading, make sure you have proper noscript fallbacks so non-JS crawlers can still index your images.
Test NitroPack yourself
Frequently asked questions
Should I lazy-load my hero image to improve page speed?
No. Lazy loading your hero image is one of the most common mistakes that hurts LCP scores. Your hero image is typically the LCP element—the largest visible content Google measures. Lazy loading it delays the exact metric you’re trying to improve. Instead, exclude your hero image from lazy loading and preload it using fetchpriority="high" to prioritize its delivery.
Will lazy loading affect my Google rankings?
Not negatively, as long as it’s implemented correctly. Native browser lazy loading is fully compatible with Googlebot—Google has no trouble crawling and indexing lazy-loaded images. The risk only arises with JavaScript-only implementations, where images might not be visible to non-JS crawlers. If you’re in that camp, adding noscript fallbacks is a good precaution. You can verify that Google is seeing your images correctly using the URL Inspection tool in Google Search Console.
Does lazy loading work for videos and iframes?
Yes, and it’s one of the most impactful places to apply it. Embedded YouTube, Vimeo, and other third-party players load heavy scripts the moment your page opens—even if nobody scrolls to them. Replacing those embeds with a video facade (a lightweight thumbnail that loads the real player only on click) can significantly reduce your Total Blocking Time.
NitroPack applies facades automatically for YouTube, Vimeo, and Wistia, alongside lazy loading for iframes and Google Maps embeds.
Can lazy loading cause layout shifts?
It can, but only if your images don’t have defined width and height attributes. Without those dimensions, the browser has no way to reserve the right amount of space before the image loads—so the layout jumps around as images appear. This shows up as a high CLS score in PageSpeed Insights.
NitroPack’s Adaptive Image Sizing adds width and height attributes automatically, which eliminates layout shifts without any extra work on your part.
What’s the difference between NitroPack and a standard lazy loading plugin?
A standard lazy loading plugin handles image deferral and not much else. NitroPack combines lazy loading with image compression, WebP conversion, adaptive sizing, and a built-in global CDN—all running from the cloud, so none of it puts load on your hosting server.
The biggest practical difference is automation: NitroPack automatically excludes above-the-fold images, applies video facades, and adds image dimensions, whereas most plugins require you to configure those things manually. There’s a free plan with no credit card required if you want to test it on your own site.