Description
The best free, simple & lightweight lazy load plugin for WordPress. Lazy loading images, videos, and iframes to improve page speed performance and Core Web Vitals scores.
Most lazy load plugins only optimize images. Smart LazyLoad goes further by deferring images, responsive <picture> sources, background images, native HTML5 videos, and iframes (including YouTube, vimeo) until they are about to enter the viewport.
Built with a lightweight, dependency-free frontend engine, Smart LazyLoad uses modern browser APIs without requiring jQuery or other third-party libraries. It also includes native browser lazy loading support, smooth loading effects, and intelligent defaults, so it works well immediately after activation.
Unlike most lazy load plugins, Smart LazyLoad gives you two levels of control. A global Master Switch lets you enable or disable lazy loading across your entire website, while a per-post override allows individual posts and pages to follow the global setting or force lazy loading on or off when needed.
Everything is managed from a clean, modern settings page where you can choose what to lazy load, fine-tune performance, customize placeholders and animations, and exclude specific elements for maximum compatibility.
Features
What gets lazy loaded
- Images — inside post/page content, featured images, widget images, and avatars.
- Responsive
<picture>sources — defers every<source>inside a<picture>element (WebP, hi-DPI, art-directed crops) in lock-step with its fallback<img>, so the browser’s format/media negotiation is never affected, only when it happens. - Background images — inline
style="background-image", a manualdata-bgattribute, and retina/responsive backgrounds via CSSimage-set()or a manualdata-bg-setattribute, picking the best resolution for the visitor’s screen. - Iframes — any embedded iframe, including YouTube and Vimeo players.
- Native
<video>— HTML5<video>tags, their<source>children, andposterimages. - YouTube click-to-play thumbnails — an optional mode that replaces a YouTube iframe with a lightweight clickable thumbnail until the visitor actually wants to watch it.
Two layers of on/off control
- A single Master Switch turns the entire plugin on or off for the whole site
- Turning the Master Switch off automatically dims and locks every other setting on the page so it can’t be edited by mistake — but nothing is ever cleared; your configuration reappears exactly as you left it the moment you switch it back on
- A Smart LazyLoad panel on the post/page editor sidebar adds a single Lazy Load dropdown — Default, Enable, or Disable — so any individual post or page can override the site-wide behavior without touching a single other post
Performance tuning
- Automatically skips lazy loading the first image on the page, protecting your Largest Contentful Paint (LCP) score
- Adjustable distance-from-viewport threshold that controls how early loading starts
- Choice between the plugin’s own IntersectionObserver-based engine or the browser’s native
loading="lazy" - Loads its own script in the footer instead of the head, so it never delays first paint
- Can be switched off entirely for logged-in users, so you always see full-quality content while editing
Appearance while content loads
- Low-quality image placeholder (LQIP): a tiny, blurred preview generated from an existing thumbnail size, shown instead of a blank box
- The preview is generated once per image and cached as post meta, so it costs nothing on later page loads
- A WP-CLI command (
wp smart-lazyload generate-lqip) pre-generates placeholders for your whole media library at once, so large sites never pay the one-time generation cost on a live visitor’s request - Pick which registered image size is used to generate the preview
- Configurable fade-in duration for the moment content finishes loading
- Optional placeholder background color, picked with the native WordPress color picker
Compatibility and control
- A multi-line custom exclude field — list your own classes or attributes to skip, no code required
- Built-in recognition of common exclusion conventions:
no-lazyload,skip-lazy,data-no-lazy,data-skip-lazy - Automatically stays out of the way inside page builder editors (Beaver Builder, Divi, Oxygen) and on feeds, previews, and REST requests
- Developer filters for replacing placeholders and disabling lazy loading conditionally
- One-click “Reset to Defaults” whenever you want to start over
Built the right way
- Zero jQuery or bundled third-party libraries on the frontend
noscriptfallbacks so content is never lost for visitors or crawlers without JavaScript- A modern, fully responsive, card-based settings screen
- Clean uninstall: removes its own options and post meta, nothing else, when you delete the plugin
Configuration
Site-wide settings: Settings LazyLoad
The settings screen is organized into five cards:
Master Switch — the single toggle that turns Smart LazyLoad on or off for the entire site. When it’s off, every card below it is dimmed and cannot be edited, but nothing about your saved configuration changes.
What to Lazy Load — independently toggle Images, Responsive <picture> Sources, Background Images, Iframes, Native Videos, and YouTube Thumbnail Replacement.
Performance — Skip First Image (for LCP), Threshold Distance, Use Native Browser Lazy Loading, Load Script in Footer, and Disable for Logged-in Users.
Appearance — Low-Quality Image Placeholder plus its source size, an optional Placeholder Background Color, and the Fade-in Duration.
Advanced — a Custom Exclude Selectors textarea for skipping elements by class or attribute without writing code.
A Reset to Defaults button at the bottom restores every option to its original value in one click.
Per-post override
Open any post, page, or public custom post type in the block editor and look for the Smart LazyLoad panel in the sidebar. Its Lazy Load dropdown has three choices:
- Default (On) or Default (Off) — label reflects the current Master Switch state; this post simply follows the site-wide setting
- Enable — lazy loading is always on for this post, even if the Master Switch is off
- Disable — lazy loading is always off for this post, even if the Master Switch is on
The choice is saved as post meta and applies only to that single post — nothing else on the site is affected.
Developer filters
do_smart_lazyload — return `false` to disable lazy loading for the current request.
smart_lazyload_svg_placeholder — replace the default inline SVG placeholder used for images.
smart_lazyload_placeholder — replace the placeholder value used for deferred iframes (default: `about:blank`).
smart_lazyload_excluded_attributes — extend the list of strings that exclude an image tag from lazy loading.
smart_lazyload_iframe_excluded_patterns — extend the list of strings that exclude an iframe tag from lazy loading.
smart_lazyload_excluded_src — extend the list of substrings checked against an image or background-image URL itself (not just its surrounding tag) to exclude it from lazy loading; useful for dynamic image generators or known placeholder assets.
Screenshots






Installation
From your WordPress dashboard
- Navigate to Plugins Add New Plugin
- Search for Smart LazyLoad
- Click Install Now, then Activate
- Go to Settings LazyLoad to review the defaults — lazy loading for images is already on out of the box
Manual upload
- Download the plugin’s ZIP file
- Upload the
lazy-load-for-imagesfolder to/wp-content/plugins/ - Activate the plugin from Plugins Installed Plugins
- Visit Settings LazyLoad to adjust anything, or leave the defaults as they are
No further setup is required — lazy loading starts working on the frontend as soon as the plugin is active.
FAQ
-
What exactly does Smart LazyLoad defer?
-
Images inside post/page content, featured images, widget images, avatars,
<picture>sources, CSS/inline background images, iframes (YouTube, Vimeo, and others), and native<video>elements. Each content type has its own on/off toggle, so you decide what applies. -
How is this different from a plugin that only lazy loads images?
-
Most lazy load plugins stop at
<img>tags. Smart LazyLoad also handles background images,<picture>responsive sources, videos, and iframes, and adds a second layer of control on top of the usual site-wide switch: a per-post override that lets a single page behave differently from the rest of the site. -
Does this work with AMP pages?
-
Yes, safely: on any page served through the AMP plugin, Smart LazyLoad detects the AMP endpoint and skips lazy loading entirely — including its scripts and styles — since AMP’s markup rules don’t allow the attributes lazy loading needs. Non-AMP pages are unaffected.
-
How do I make one specific post behave differently from the rest of the site?
-
Open that post or page in the editor and find the Smart LazyLoad panel in the sidebar. Set the Lazy Load dropdown to Enable to force lazy loading on for that post only, or Disable to force it off — either way, every other post keeps following the site-wide Master Switch untouched.
-
If I turn the Master Switch off, do I lose my other settings?
-
No. Every other option on the settings page is dimmed and can’t be edited while the Master Switch is off, but its saved value is untouched. Turn the Master Switch back on and your previous configuration is exactly as you left it.
-
How do I exclude one image, video, or iframe from being lazy loaded?
-
Add any of these to the element:
no-lazyload,skip-lazy,data-no-lazy, ordata-skip-lazy. For your own classes or attributes, list them (comma-separated) under Settings LazyLoad Custom Exclude Selectors — no code needed. -
Can I disable lazy loading with code instead of the settings page?
-
Yes.
add_filter( 'do_smart_lazyload', '__return_false' );Or conditionally, for example only on single posts:
add_action( 'wp', function () { if ( is_single() ) { add_filter( 'do_smart_lazyload', '__return_false' ); } } ); -
Does it support background images?
-
Yes, in two ways. Automatically, for any element using the inline style attribute:
<div style="background-image: url(photo.jpg);">Or manually, using the plugin’s own markup convention:
<div class="smart-background" data-bg="url(photo.jpg)"></div> -
Does it support responsive “ markup?
-
Yes. Every
<source>inside a<picture>element has itssrcset/sizesdeferred in sync with the fallback<img>. The browser still decides which source to use based on format and viewport — Smart LazyLoad only changes when the chosen source loads. -
What is the low-quality image placeholder (LQIP)?
-
When turned on, Smart LazyLoad shows a tiny, blurred version of the real image (generated from a registered thumbnail size) instead of an empty box while the full image loads. It’s generated once per image, cached, and reused on every later page view. Choose the source size under Settings LazyLoad Placeholder Source Size.
On a large, existing media library, the first visitor to view each image pays a small one-time generation cost. Avoid that entirely by pre-generating every placeholder in advance from the command line:
wp smart-lazyload generate-lqipAdd
--forceto regenerate placeholders that are already cached (useful after changing the Placeholder Source Size). -
Can I use my own placeholder image instead of the built-in SVG?
-
Yes.
add_filter( 'smart_lazyload_svg_placeholder', function () { return 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1 1"></svg>'; } );Deferred iframes use a separate placeholder (default
about:blank), which you can change with:add_filter( 'smart_lazyload_placeholder', function () { return 'about:blank'; } ); -
Will this conflict with my caching, CDN, or other performance plugins?
-
No. Smart LazyLoad only changes the HTML markup for images, videos, and iframes on the fly; it doesn’t touch how pages are cached or served, so it works alongside typical caching and CDN setups.
-
Is Smart LazyLoad SEO-friendly?
-
Yes. Deferred content is always wrapped with a working
<noscript>fallback, native browser lazy loading is supported directly, and the first image on the page is skipped by default so it doesn’t hurt your Largest Contentful Paint score. -
Lazy loading doesn’t seem to be working. What should I check?
-
- Confirm the Master Switch is on, and that the specific post isn’t set to Disable in its Lazy Load panel
- Clear any page cache, CDN cache, or browser cache
- Check whether “Disable for Logged-in Users” is on and you’re viewing the page while logged in
- Temporarily disable other lazy load plugins to rule out a conflict
- Make sure the element doesn’t carry one of the exclusion classes/attributes
- View the actual frontend page, not a page-builder editing screen or preview
Reviews
Contributors & Developers
“Smart LazyLoad – Lazy Load Images, Videos and Iframes” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Smart LazyLoad – Lazy Load Images, Videos and Iframes” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
2.9.0
- Improved: images and sources are now detected reliably even when a theme writes multi-line or unusually spaced HTML markup
- Improved: internal code cleanup for better long-term maintainability
2.8.0
- Added: automatic AMP compatibility — lazy loading, its inline scripts/styles, and the enqueued frontend script/stylesheet are all skipped on AMP endpoints (detected via the AMP plugin’s is_amp_endpoint()), since AMP markup validation rejects the custom classes, data attributes, and inline scripts lazy loading depends on
2.7.0
- Fixed: markup-like text inside existing script or noscript blocks (for example, an img tag written inside a JS string, or a manually authored noscript fallback) could be corrupted or doubled up by the lazy-load processing; such blocks are now protected and passed through untouched
- Added: a src-pattern exclusion list (smart_lazyload_excluded_src filter) so known dynamic image generators, form captchas, and common placeholder assets are never lazy-loaded, on both images and background images
2.6.0
- Added: retina/responsive background image support via CSS image-set()/-webkit-image-set(), or a manual data-bg-set attribute, automatically picking the best resolution for the visitor’s screen
- Added: a WP-CLI command, wp smart-lazyload generate-lqip, to pre-generate low-quality image placeholders for an entire media library up front (with a –force option to regenerate)
- Fixed: the YouTube click-to-play thumbnail’s aria-label was a hardcoded English string that never passed through translation functions
- Changed: the Threshold Distance field now uses the same CSS-only locking approach as the Master Switch cards (instead of the HTML disabled attribute) when Native Browser Lazy Loading is on, for a more consistent settings UI
2.5.0
- Changed: the YouTube click-to-play thumbnail’s play button icon is now a bundled local image (assets/img/youtube.png) instead of an external request; the per-video thumbnail image itself is unaffected and still loads from YouTube
- Changed: background-image lazy loading now uses its own dedicated class, smart-background, alongside the shared smart-lazyload marker, avoiding any overlap between the two lazy-load selector groups
2.4.1
- New: a “Smart LazyLoad” panel in the post/page editor sidebar with a single Lazy Load dropdown (Default / Enable / Disable) to override the site-wide setting for one post at a time
- New: the settings page now dims and locks every option below the Master Switch while it’s off; saved values are always preserved and reappear the moment it’s switched back on
- Fixed: saving the settings form for the very first time (fresh install, or right after Reset to Defaults) could silently re-enable every checkbox regardless of what was actually checked
- Fixed: the low-quality placeholder no longer runs its image-processing step on wp-admin screens, where it had no effect but still cost CPU time
- Fixed: a stray double space left in background-image tag output after removing an empty inline style attribute
- Changed: settings-page CSS classes, IDs, and the settings page slug now use a consistent naming scheme (visual and behavior are unchanged)
2.4.0
- Fixed: a JavaScript error thrown on page load when the lazy-load observer initialized before
<body>existed - Fixed: background images were swapped to their real URL but never marked as loaded, leaving them invisible
- Fixed:
<picture>elements had their<img>lazy-loaded by the Images option even when the picture option was off, leaving<source>and<img>out of sync;<picture>is now handled entirely by its own toggle - Changed: trimmed the frontend script down to only the code paths this plugin uses
- Changed: Custom Exclude Selectors is now a multi-line textarea
- Changed: Placeholder Background Color now uses the native WordPress color picker
- Changed: redesigned the settings page with a card-based layout and toggle switches
2.3.0
- Fixed: mismatched class names between the frontend script/CSS and the PHP handlers, which had prevented lazy loading, fade-in, and the YouTube thumbnail mode from working
- Fixed: settings were saved under a different option name than the one the frontend read, so saved changes never took effect
- Fixed: a class name mismatch in the background-image handler that could trigger a fatal error
- Fixed: admin assets were enqueued from the wrong path and on the wrong admin screen
- Fixed: the Reset to Defaults button posted to a handler that didn’t match its registered action
- Removed: the inline CSS/JS loading mode
- Added: an option to load the script in the footer instead of the head
2.2.0
- Added: lazy loading for
<picture>elements, deferring each<source>‘s srcset/sizes - Added: low-quality image placeholder (LQIP) option with a cached, blurred preview
- Added: a setting to choose which registered image size generates the LQIP preview
- Changed: base CSS now ships as a small external stylesheet instead of being inlined on every page
2.1.0
- Added: native
<video>lazy loading, including<source>tags and poster images - Added: configurable fade-in duration (previously fixed at 0.3s)
- Added: optional placeholder background color
- Added: Custom Exclude Selectors setting
- Added: Reset to Defaults action, with capability and nonce checks
- Removed: two unused asset files left over from an earlier version
2.0.2
- Fixed: saving settings while native lazy loading was enabled reset the threshold value back to its default
- Readme: removed an unverifiable superlative claim from the plugin description
2.0.1
- Verified compatibility with WordPress 7.0.2 and PHP 8.0–8.4
- Fixed: a missing translators comment on a string with placeholders
- Added: uninstall cleanup of the plugin’s settings (multisite-aware)
2.0.0
- Complete rewrite adding iframe, video, and background-image lazy loading
- Added: YouTube thumbnail replacement mode
- Rebuilt the admin settings page
- General performance and stability improvements
1.5
- Tested with WordPress 6.5.2
- JavaScript and PHP fixes
- Added SVG placeholder support
1.4.x
- Genesis framework compatibility
- Hook and filter improvements
- General bug fixes
1.0.0
- Initial release
