Written by 3:16 am How To, WordPress Views: 5

WordPress Lazy Loading: Images, Iframes, and Comments

Learn every WordPress lazy loading technique: native loading=lazy, the wp_lazy_loading_enabled filter, iframe lazy loading, comment pagination, and the Intersection Observer API for custom implementations.

WordPress Lazy Loading: How to Implement for Images, Iframes, and Comments

Lazy loading is one of the highest-ROI performance optimization techniques available in WordPress. The concept is straightforward: do not load resources until they are needed. Images below the fold, iframes for embedded videos, and even comment sections can all be deferred until the user actually scrolls to them. The browser loads less on initial page load, your Largest Contentful Paint time improves, and users on slow connections get a usable page faster. This guide covers every WordPress lazy loading technique available – native browser support, the wp_lazy_loading_enabled filter, lazy-loaded comment sections, and the Intersection Observer API for custom implementations.

Detailed view of HTML code on a computer screen representing WordPress lazy loading implementation.

Native loading=lazy: What It Is and How WordPress Uses It

The HTML loading attribute is the simplest form of WordPress lazy loading. Add loading=lazy to an img or iframe element and the browser defers loading that resource until it comes within a certain distance of the viewport. No JavaScript required. Native lazy loading is supported in all modern browsers as of 2021 and covers over 95% of users globally. For the vast majority of WordPress sites, native lazy loading is safe to rely on without a JavaScript fallback.

WordPress added native lazy loading for images in version 5.5 (August 2020). Since then, it has expanded to cover more image contexts and added intelligent LCP optimization:

  • WordPress 5.5+ – Automatically adds loading=lazy to all img tags rendered by core functions
  • WordPress 5.9+ – Adds loading=lazy to iframe elements in post content
  • WordPress 6.3+ – LCP image detection: identifies the likely LCP image and adds fetchpriority=high to it while skipping loading=lazy for above-fold images

The automatic LCP handling in WordPress 6.3+ is significant. A common mistake with WordPress lazy loading is applying it to the hero image, which delays the LCP element and hurts Core Web Vitals. WordPress now handles this automatically for core images – it adds loading=eager to the first images and loading=lazy to images further down the page.


wp_lazy_loading_enabled Filter

WordPress provides the wp_lazy_loading_enabled filter to control lazy loading behavior programmatically. This filter fires whenever WordPress decides whether to add loading=lazy to an element.

Filter Arguments

Common Use Cases

Disable WordPress lazy loading on specific post types:

Disable lazy loading on the admin side:

Disable only for iframes while keeping image lazy loading:

wp_get_attachment_image_attributes Filter

For fine-grained control over individual image attributes, use wp_get_attachment_image_attributes. This fires for every image processed through wp_get_attachment_image() and lets you modify any HTML attribute including the loading, fetchpriority, and decoding values.


Lazy Loading Images Not Processed by WordPress

WordPress automatic lazy loading only applies to images processed through core functions like wp_get_attachment_image(), the_post_thumbnail(), and images inserted via the block editor. Images in themes, custom HTML, or plugins that bypass these functions do not get WordPress lazy loading automatically.

WordPress 6.0 added the wp_content_img_tag filter, which fires for every img tag found in post content. This is the right hook to add loading=lazy to images that core processing missed.

Before wp_content_img_tag, developers used regex on the_content to add lazy loading attributes. This approach still works for backward compatibility or for modifying images outside post content.


Lazy Loading Iframes

Iframes are often heavier than images. An embedded YouTube video loads the entire YouTube player JavaScript, CSS, and thumbnail even before the user plays it. A page with 3-4 YouTube embeds can add 1-2MB to the page weight just from iframe content. WordPress lazy loading for iframes has an outsized impact on performance.

WordPress 5.9+ adds loading=lazy to iframes in post content automatically. For iframes outside post content (in themes, widgets, page builders), you need to add the attribute manually.

YouTube Facade Pattern (Better for Performance)

For YouTube embeds specifically, the facade pattern is more effective than native lazy loading. Instead of loading the YouTube iframe at all until the user interacts, you show a lightweight thumbnail image. Only when the user clicks does the actual YouTube iframe load. This approach can save 400-500KB on pages with YouTube embeds and is significantly better for Core Web Vitals than simply applying loading=lazy to iframes.


Lazy Loading WordPress Comments

On posts with hundreds of comments, the comment section adds significant load to every page view, even for users who never scroll to it. The better approach for WordPress lazy loading of comments is to not load them at all until the user scrolls to or clicks on the comment section.

The most effective method uses the Intersection Observer API to automatically load comments when the comment section comes into view, without requiring a user click. This is transparent to users but still defers the comment load until it is actually needed.

For sites that want a simpler solution, WordPress built-in comment pagination (Settings – Discussion – Break comments into pages) reduces comment payload size. Set the default page to last so readers see the most recent comments by default.


Intersection Observer API: The JavaScript Foundation

The Intersection Observer API is the modern JavaScript method for detecting when an element enters or exits the viewport. It powers all JavaScript-based lazy loading and is the recommended replacement for scroll event listeners, which are expensive and cause jank.

The rootMargin option controls how far in advance the observer fires. Setting rootMargin to 200px means the callback fires when the element is 200px away from the viewport, giving you time to start loading before the element is actually visible. This prevents the blank flash problem where lazy-loaded content visibly pops in as the user scrolls. Beyond images and iframes, Intersection Observer is useful for any heavy content that should not load until needed: Google Maps loads a substantial JavaScript payload and is an ideal candidate for lazy loading via Intersection Observer.


WordPress Lazy Loading with Page Builders

Page builders like Elementor, Divi, and Beaver Builder add their own optimization layers on top of WordPress core, and this can create conflicts or redundancies with WordPress lazy loading. Understanding how each major page builder handles lazy loading prevents images from being loaded twice or not at all, and helps you configure the right combination of settings for your specific stack.

Elementor and WordPress Lazy Loading

Elementor has its own lazy loading feature built into the Image widget and Background Image functionality. By default, Elementor applies its own lazy loading implementation alongside WordPress core lazy loading. This can result in images having both the native loading=lazy attribute and Elementor JavaScript-based lazy loading active simultaneously. In most cases this is harmless – native lazy loading takes precedence and Elementor JavaScript detects the attribute and defers to it. But on sites with caching issues or minification conflicts, the dual implementation can cause images to appear blank on initial scroll. The safest configuration: in Elementor settings under Performance, leave Elementor lazy loading enabled but disable it for the first image in each section to prevent accidentally lazy loading LCP elements.

Divi and WordPress Lazy Loading

Divi uses its own lazy loading system through its image optimization settings. When both Divi lazy loading and WordPress core lazy loading are active, there can be a race condition on scroll. Test your Divi site in Chrome DevTools Network tab to verify images are actually being deferred and not blocked entirely. If you are using WP Rocket alongside Divi, disable Divi built-in lazy loading in Divi Theme Options under Performance and let WP Rocket handle it. WP Rocket implementation is more comprehensive and better integrated with WordPress core lazy loading behavior.

Beaver Builder and WordPress Lazy Loading

Beaver Builder does not add its own custom lazy loading and instead relies on WordPress core. This means native WordPress lazy loading works cleanly with Beaver Builder without configuration changes. The only exception is background images set in Beaver Builder row settings – these are output as inline CSS and are not handled by native loading=lazy. Use WP Rocket or a custom Intersection Observer implementation to handle Beaver Builder background images if they are large enough to affect performance. When using any page builder, pick one WordPress lazy loading system and disable the others to prevent redundant overhead.


WordPress Lazy Loading and WooCommerce

WooCommerce stores require special care with WordPress lazy loading because product images serve a commercial function. Load delays on product pages directly affect conversion rates, not just performance metrics, so the standard approach needs refinement for WooCommerce sites.

Product archive pages (shop, category, and tag archives) are the best candidates for aggressive WordPress lazy loading. These pages display grids of product images that are mostly below the fold on first load. WordPress lazy loading applies to these images automatically when they are output through wp_get_attachment_image() or the_post_thumbnail(), which most WooCommerce themes use. Custom WooCommerce archive templates that bypass these functions need the loading attribute added manually via the wp_get_attachment_image_attributes filter to ensure WordPress lazy loading activates on every product card in the grid.

Single product pages require more conservative treatment. The main product image and the first gallery thumbnail visible on initial load are typically the LCP element on the page and should never be lazy-loaded. Apply loading=eager and fetchpriority=high to these images explicitly. Additional gallery images that require scrolling or an interaction to reveal are valid WordPress lazy loading candidates. After making changes to product gallery lazy loading, test gallery JavaScript with network throttling active in Chrome DevTools to catch any initialization conflicts with WooCommerce gallery scripts.

Always configure explicit width and height dimensions for WooCommerce product images via Appearance – Customize – WooCommerce – Product Images. Without explicit dimensions, lazy-loaded product images cause Cumulative Layout Shift when they finish loading, which directly hurts Core Web Vitals CLS scores. Fixing product image dimensions is a prerequisite for WordPress lazy loading to improve Core Web Vitals rather than hurting them on WooCommerce stores. For tips on improving your store’s visual presentation alongside performance, see our WordPress design guides.


Measuring the Impact of WordPress Lazy Loading

Lazy loading improvements show up in specific metrics. For a full picture of WordPress performance opportunities, see our WordPress performance audit checklist.

Metric Where to Check Expected Improvement
LCP PageSpeed Insights, Lighthouse 0.3-1.5s reduction on image-heavy pages
Total Blocking Time Lighthouse, WebPageTest Reduced if lazy-loading defers JS-heavy embeds
Total page size Network tab, WebPageTest 30-60% reduction on image-heavy pages
Number of requests Network tab Significant reduction for multi-embed pages
Time to Interactive Lighthouse Reduced when heavy iframes are deferred

The biggest gains come on pages with multiple images or embeds that are mostly below the fold on first load. A long-form blog post with 15 images and 3 YouTube embeds will see substantial changes after implementing WordPress lazy loading. A single-image landing page will see minimal improvement.


Common Pitfalls with WordPress Lazy Loading

  • Lazy loading the LCP image – Never apply WordPress lazy loading to the first image visible in the viewport. WordPress 6.3+ handles this automatically for core images, but custom implementations must be careful. Use Lighthouse to identify your LCP element and verify it is not lazy-loaded.
  • Missing width and height attributes – Lazy-loaded images without explicit width/height dimensions cause Cumulative Layout Shift (CLS) when they load. Always include dimensions, or use CSS aspect-ratio to reserve space.
  • Lazy loading CSS background images – The native loading attribute does not work on CSS background images. Use Intersection Observer or a plugin like WP Rocket. See our WordPress hooks guide for filter patterns that support conditional loading.
  • Breaking SEO – Google crawler handles native WordPress lazy loading correctly. But complex JavaScript-based lazy loading that hides images from the DOM initially may prevent crawling. Test with Google Search Console URL Inspection tool.
  • Lazy loading above-fold product images – WooCommerce product page hero images and gallery images should never be lazy-loaded. They are critical for conversion and should load as fast as possible.

WordPress Lazy Loading Plugins

If you prefer a plugin-based approach, several WordPress plugins handle lazy loading well. Smush from WPMU DEV applies loading=lazy to images throughout the site with options to exclude specific images by CSS class. Optimole combines image optimization, CDN delivery, and WordPress lazy loading in a cloud-based service that replaces your image URLs with CDN URLs. WP Rocket is the gold standard for all-in-one WordPress performance optimization – its WordPress lazy loading implementation covers images, iframes, videos, and background images, and also handles the YouTube facade pattern out of the box.

Scenario Recommended Approach
Standard site, non-developer Use a plugin (Smush, Optimole, or WP Rocket)
Developer-managed site, custom requirements Native WordPress filters + custom code
Performance-critical site with complex rules Custom Intersection Observer implementation
Already using WP Rocket Enable WP Rocket built-in lazy loading
Need CDN integration with lazy loading Optimole or WP Rocket with CDN

Accessibility Considerations for WordPress Lazy Loading

Native loading=lazy is fully accessible – screen readers handle lazy-loaded images the same way they handle any other images, as long as proper alt text is present. JavaScript-based WordPress lazy loading that initially hides images from the DOM requires more care: ensure hidden images are also hidden from the accessibility tree until they load, and that the loading state is communicated appropriately to assistive technologies. Many WordPress lazy loading implementations add a fade-in animation when content loads. Respect the prefers-reduced-motion media query and disable or reduce these animations for users who have indicated a preference for reduced motion.


Testing Your WordPress Lazy Loading Implementation

Verifying that lazy loading is working correctly requires testing in multiple contexts. Use Chrome DevTools Network tab filtered by Img to watch which images load on page load vs on scroll – images that should be lazy should show as pending until you scroll to them. Run PageSpeed Insights before and after to look for LCP improvement and reduction in Total Bytes. Use Google Search Console URL Inspection to render your page as Googlebot sees it and verify that lazy-loaded images are visible in the rendered screenshot. In Chrome DevTools, throttle to Slow 3G and verify that content placeholders are properly sized to prevent layout shift during loading.


WordPress Lazy Loading Implementation Checklist

With multiple WordPress lazy loading approaches available, this priority checklist helps you implement in the right order for maximum impact with minimum risk to existing page performance.

Phase 1: Verify Core WordPress Lazy Loading is Working

  • Confirm WordPress version is 5.5 or later (Settings – General – Update)
  • Open Chrome DevTools Network tab, filter by Img, and load a content-heavy page
  • Scroll through the page and verify below-fold images load progressively as you scroll
  • Check that the first image loads immediately and has fetchpriority=high on the LCP image (WordPress 6.3+)
  • Verify no images visible in the viewport are marked as lazy in the HTML source

Phase 2: Address Images Outside WordPress Core Processing

  • Identify all images inserted via direct HTML, custom theme templates, or page builder widgets that bypass core image functions
  • Use the wp_content_img_tag filter (WordPress 6.0+) to add loading=lazy to content images that core processing missed
  • For theme template images, add the loading attribute directly or use the wp_get_attachment_image_attributes filter
  • Re-run PageSpeed Insights and compare the initial request count before and after to confirm impact

Phase 3: Tackle Iframes and Video Embeds

  • Audit all YouTube and video embeds on high-traffic pages – these are typically the largest performance wins
  • Implement the YouTube facade pattern for embeds on pages where video is supplementary rather than primary content
  • Add loading=lazy manually to any iframes outside post content (widget areas, theme templates, page builder sections)
  • Verify Google Maps and other heavy third-party embeds are deferred via Intersection Observer or WP Rocket

Phase 4: Measure and Iterate

  • Run PageSpeed Insights on your three highest-traffic pages after implementing WordPress lazy loading
  • Compare LCP scores before and after and note which pages saw the largest improvement
  • Check Core Web Vitals in Google Search Console for site-wide impact over the next 28-day period
  • Address any CLS issues caused by lazy-loaded images missing explicit width and height dimensions
  • If using Elementor, Divi, or another page builder, verify no conflict with WordPress lazy loading

Most sites see the majority of their WordPress lazy loading gains from Phase 1 and Phase 3 alone. Core images are handled automatically by WordPress, and YouTube embeds are typically the biggest individual wins on most content sites. Phases 2 and 4 serve as polish and verification steps that help you close the remaining performance gaps.


Frequently Asked Questions

Does WordPress lazy loading hurt SEO?

No, when implemented correctly. Google crawler fully renders JavaScript and handles both native loading=lazy and Intersection Observer-based WordPress lazy loading. Images deferred by native lazy loading are still indexed because Googlebot scrolls the page during rendering and triggers lazy-loaded images to load. The risk comes from custom JavaScript implementations that hide images from the DOM entirely until interaction. Always verify your pages with Google Search Console URL Inspection tool after any WordPress lazy loading changes.

Should I apply WordPress lazy loading to the hero image?

Never. The hero image is almost always your Largest Contentful Paint element. Applying WordPress lazy loading to it delays the LCP metric, which directly harms your Core Web Vitals score. The hero image should load as fast as possible with fetchpriority=high and loading=eager. WordPress 6.3+ handles this automatically for images inserted via the block editor, but check manually for hero images set via theme customizer or custom theme templates.

How does WordPress lazy loading interact with page caching?

Native loading=lazy is baked into the HTML and works transparently with all WordPress caching plugins. The attribute is in the cached HTML and the browser handles the rest. JavaScript-based WordPress lazy loading requires that the caching plugin serves the lazy loading JavaScript correctly. Most major caching plugins (WP Rocket, W3 Total Cache, WP Super Cache) handle this well. Watch out for JavaScript minification combining your lazy loading script in ways that break initialization – verify in an incognito window with caching active.

Can I lazy load CSS background images in WordPress?

CSS background images set in stylesheets cannot use the native loading attribute, which only works on img and iframe HTML elements. For CSS background images, the standard pattern is to set the background image URL in a data-bg attribute instead of directly in CSS, then use Intersection Observer to swap it into the actual CSS background property when the element enters the viewport. WP Rocket handles CSS background image WordPress lazy loading automatically for elements in its detection scope. For background images set via the WordPress customizer using inline styles, JavaScript can target those inline style attributes directly.

More WordPress Performance Tweaks

WordPress lazy loading is one tool in the performance optimization toolkit. For more advanced techniques, check out our performance category on TweaksWP, covering caching strategies, database optimization, and Core Web Vitals improvements that move the needle on real-world page speed.

Visited 5 times, 1 visit(s) today

Last modified: March 26, 2026