Comprehensive WordPress Lazy Load Plugin Code
All-inclusive plugin code for lazy loading images everywhere
Highlights
- Full functionality: Implements lazy loading for all image types (WebP, PNG, SVG, etc.) across single posts, pages, homepages, feature images, content images, and sidebar images.
- User-configurable settings: Dashboard options provide selections for preloaded images (SVG, PNG, WebP) and more.
- Structured file organization: Comprehensive code with clear file paths, functions, and integration with WordPress Settings API for an intuitive admin dashboard.
Overview
This guide offers a complete WordPress plugin solution that implements lazy loading for various image formats across your website sections. The plugin will ensure images on single posts, pages, the homepage, feature images, in-content images, and sidebar images load only when they are needed, significantly enhancing page speed and performance. Additionally, the plugin includes a settings page in the dashboard to allow users to select a preload image style (e.g., SVG, PNG, WebP) before lazy loading the actual content.
Plugin Structure and File Organization
The plugin is organized into multiple files and directories under a main directory called lazy-load-images inside your wp-content/plugins/ folder. Below is the file structure:
| File/Folder | Description | Path |
|---|---|---|
| Main Plugin File | Entry point for the plugin initialization | wp-content/plugins/lazy-load-images/lazy-load-images.php |
| Settings File | Dashboard settings page for preload image selection | wp-content/plugins/lazy-load-images/settings.php |
| Functions | Contains plugin functionality for processing images | wp-content/plugins/lazy-load-images/includes/functions.php |
| Helpers | Helper functions to output dynamic preload URLs | wp-content/plugins/lazy-load-images/includes/helpers.php |
| JavaScript | Lazy loading script for handling image scrolling events | wp-content/plugins/lazy-load-images/assets/js/lazy-load-images.js |
| CSS | Styling for lazy loading classes | wp-content/plugins/lazy-load-images/assets/css/lazy-load-images.css |
| Preload Images | Default images used before actual loading | wp-content/plugins/lazy-load-images/assets/images/ |
Complete Plugin Code
1. Main Plugin File - lazy-load-images.php
<?php
/*
Plugin Name: Lazy Load Images
Description: A powerful plugin to lazy load images across your WordPress site (single posts, pages, homepage, feature images, content images, and sidebar images) supporting multiple formats like WebP, PNG, SVG, etc.
Version: 1.0
Author: Your Name
*/
// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Define plugin directory path and URL
define( 'LLI_DIR', plugin_dir_path( __FILE__ ) );
define( 'LLI_URL', plugin_dir_url( __FILE__ ) );
// Include necessary files
require_once LLI_DIR . 'includes/functions.php';
require_once LLI_DIR . 'includes/helpers.php';
require_once LLI_DIR . 'settings.php';
// Enqueue plugin scripts and styles
function lli_enqueue_scripts() {
wp_enqueue_script( 'lli-lazy-load', LLI_URL . 'assets/js/lazy-load-images.js', array('jquery'), '1.0', true );
wp_enqueue_style( 'lli-styles', LLI_URL . 'assets/css/lazy-load-images.css' );
}
add_action( 'wp_enqueue_scripts', 'lli_enqueue_scripts' );
// Add settings menu in admin dashboard
function lli_add_admin_menu() {
add_menu_page( 'Lazy Load Images Settings', 'Lazy Load Images', 'manage_options', 'lazy-load-images', 'lli_settings_page', 'dashicons-format-image', 81 );
}
add_action( 'admin_menu', 'lli_add_admin_menu' );
?>
2. Settings Page File - settings.php
<?php
// Settings page callback function
function lli_settings_page() {
?>
<div class="wrap">
<h1>Lazy Load Images Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields( 'lli_options_group' ); // Settings group name
do_settings_sections( 'lazy-load-images' );
?>
<table class="form-table">
<tr valign="top">
<th scope="row">Preload Image</th>
<td>
<select name="lli_preload_image">
<option value="preload-svg.svg" <?php selected( get_option( 'lli_preload_image' ), 'preload-svg.svg' ); ?>>SVG</option>
<option value="preload-png.png" <?php selected( get_option( 'lli_preload_image' ), 'preload-png.png' ); ?>>PNG</option>
<option value="preload-webp.webp" <?php selected( get_option( 'lli_preload_image' ), 'preload-webp.webp' ); ?>>WebP</option>
</select>
</td>
</tr>
</table>
<?php submit_button( 'Save Changes' ); ?>
</form>
</div>
<?php
}
// Register settings
function lli_register_settings() {
register_setting( 'lli_options_group', 'lli_preload_image' );
}
add_action( 'admin_init', 'lli_register_settings' );
?>
3. Functions File - includes/functions.php
<?php
// Function to lazy load all images within post content
function lli_lazy_load_images_content( $content ) {
if( is_single() || is_page() ) {
// Use DOMDocument to modify img tags
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML( $content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
foreach( $dom->getElementsByTagName('img') as $img ) {
$src = $img->getAttribute('src');
$srcset = $img->getAttribute('srcset');
$sizes = $img->getAttribute('sizes');
$currentClass = $img->getAttribute('class');
// Append custom lazy class and modify attributes
$img->setAttribute( 'class', $currentClass . ' lli-lazyload' );
$img->setAttribute( 'data-src', $src );
if( !empty( $srcset ) ) {
$img->setAttribute( 'data-srcset', $srcset );
}
if( !empty( $sizes ) ) {
$img->setAttribute( 'data-sizes', $sizes );
}
// Optionally remove src attribute so browser will load preload image from CSS
$img->removeAttribute( 'src' );
}
return $dom->saveHTML();
}
return $content;
}
add_filter( 'the_content', 'lli_lazy_load_images_content' );
// Function to lazy load post thumbnail (featured image)
function lli_lazy_load_post_thumbnail( $html ) {
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML( $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
foreach( $dom->getElementsByTagName('img') as $img ) {
$src = $img->getAttribute('src');
$srcset = $img->getAttribute('srcset');
$sizes = $img->getAttribute('sizes');
$currentClass = $img->getAttribute('class');
$img->setAttribute( 'class', $currentClass . ' lli-lazyload' );
$img->setAttribute( 'data-src', $src );
if( !empty( $srcset ) ) {
$img->setAttribute( 'data-srcset', $srcset );
}
if( !empty( $sizes ) ) {
$img->setAttribute( 'data-sizes', $sizes );
}
$img->removeAttribute( 'src' );
}
return $dom->saveHTML();
}
add_filter( 'post_thumbnail_html', 'lli_lazy_load_post_thumbnail' );
// Lazy loading images in widget areas (sidebar)
function lli_lazy_load_sidebar_images( $widget_text ) {
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML( $widget_text, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
foreach( $dom->getElementsByTagName('img') as $img ) {
$src = $img->getAttribute('src');
$srcset = $img->getAttribute('srcset');
$sizes = $img->getAttribute('sizes');
$currentClass = $img->getAttribute('class');
$img->setAttribute( 'class', $currentClass . ' lli-lazyload' );
$img->setAttribute( 'data-src', $src );
if( !empty( $srcset ) ) {
$img->setAttribute( 'data-srcset', $srcset );
}
if( !empty( $sizes ) ) {
$img->setAttribute( 'data-sizes', $sizes );
}
$img->removeAttribute( 'src' );
}
return $dom->saveHTML();
}
add_filter( 'widget_text', 'lli_lazy_load_sidebar_images' );
?>
4. Helpers File - includes/helpers.php
<?php
// Get preload image URL based on the settings option
function lli_get_preload_image_url() {
$preload_image = get_option( 'lli_preload_image', 'preload-svg.svg' );
return LLI_URL . 'assets/images/' . $preload_image;
}
?>
5. JavaScript File - assets/js/lazy-load-images.js
<?php
(function() {
// Wait for the DOM content to be loaded
document.addEventListener("DOMContentLoaded", function() {
// Select all images marked for lazy loading
var lazyImages = document.querySelectorAll('img.lli-lazyload');
var options = {
root: null,
rootMargin: "0px",
threshold: 0.1
};
// Intersection Observer callback function
var loadImages = function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var img = entry.target;
if (img.dataset.src) {
img.src = img.dataset.src;
}
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
if (img.dataset.sizes) {
img.sizes = img.dataset.sizes;
}
img.classList.remove("lli-lazyload");
observer.unobserve(img);
}
});
};
// Create observer if supported
if ("IntersectionObserver" in window) {
var observer = new IntersectionObserver(loadImages, options);
lazyImages.forEach(function(img) {
observer.observe(img);
});
} else {
// Fallback: load all images immediately if IntersectionObserver not supported
lazyImages.forEach(function(img) {
if (img.dataset.src) {
img.src = img.dataset.src;
}
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
if (img.dataset.sizes) {
img.sizes = img.dataset.sizes;
}
img.classList.remove("lli-lazyload");
});
}
});
})();
?>
6. CSS File - assets/css/lazy-load-images.css
/* Define preload styling using background image */
.lli-lazyload {
background: url(<?php echo lli_get_preload_image_url(); ?>) center center no-repeat;
background-size: cover;
opacity: 0.5;
transition: opacity 0.5s ease-in-out;
}
.lli-lazyload[src] {
opacity: 1;
}
Installation and Configuration
Step-by-step Process
1. Create a directory named lazy-load-images in wp-content/plugins/.
2. Inside this directory, create the following structure as described above:
lazy-load-images.phpsettings.phpincludes/functions.phpincludes/helpers.phpassets/js/lazy-load-images.jsassets/css/lazy-load-images.cssassets/images/(Include your preload images:preload-svg.svg,preload-png.png,preload-webp.webp)
3. Copy and paste the corresponding code snippets into the matching files ensuring that the file names and paths are as indicated.
4. Log in to your WordPress dashboard, navigate to Plugins → Add New and click on Upload Plugin if you wish to install via a ZIP archive, or simply activate the plugin if added manually via FTP.
5. Once activated, a new menu titled Lazy Load Images will appear in your admin sidebar. Go there to configure your settings including which preload image format to use.
Further Customizations and Testing
Testing in Different Scenarios
After installation, test the plugin by navigating through various sections of your website:
- Check single post pages to confirm that both featured images and in-content images are loading via lazy loading.
- Examine the homepage and other static pages to observe the lazy loading effect.
- Inspect images within sidebars and widget areas.
Use browser developer tools to monitor network calls and confirm that images are loaded only when their container scrolls into view. Adjust the JavaScript Intersection Observer options if you need different threshold values or root margins for better performance.
Advanced Modifications
You may enhance this plugin further by adding:
- Support for lazy loading background images on CSS elements.
- A fallback mechanism, such as noscript tags, for older browsers.
- Integration with caching plugins to optimize lazy loading performance.
- Conditional loading based on device type or viewport size.
For advanced requirements, consider tweaking the plugin to dynamically replace placeholders with actual image sources upon viewport intersection.
References
- Rocket Lazy Load - WordPress.org
- Lazy Load for Images - WordPress.org
- How to Lazy Load Images - weDevs
- WordPress Lazy Load - WP Engine®
- Lazy Load Images in WordPress - WPBeginner
Recommended Queries for Further Insight
Last updated March 23, 2025