How to LazyLoad images in WordPress without using a WP Plugin

This post explains how to use the jQuery Lazy library in a WordPress template.

By implementing this library into a template manually will give you greater flexibility in terms of which images can be 'lazy loaded'.

A couple of requirements are necessary before using the jQuery Lazy library:

  • Requires at least jQuery 3.4.1 -- This means the default library used by WordPress will need to be disabled, and version 3.4.1 will need to be loaded.
  • Image tags to be replaced and custom functions added.

Step 1: Converting your image tags

Go through your theme and you should have image tags similar to:

<img src="/assets/img/example-image.png" alt="Example image alt" class="example_img_class">

Wrap this tag in a custom function, which will add the required Lazy load tags:

<?php echo filter_lazyload_img('<img src="/assets/img/example-image.png" alt="Example image alt" class="example_img_class">'); ?>

If you're using inline background images such as:

<div class="bg_image" style="background-image: url(/assets/img/example-image.png)">
    <div class="overlay"></div>
</div>

Also, wrap these in a custom function:

<?php echo filter_lazyload_bg('<div class="bg_image" style="background-image: url(/assets/img/example-image.png);"><div class="overlay"></div></div>'); ?>

Step 2: Load the jQuery scripts and setup LazyLoad instance

In your functions.php file, add the code shown below. This will load the required jQuery files, the Lazy library and setup a new instance of LazyLoad:

if (!is_admin()) {
    //Remove WordPress default jQuery
    wp_deregister_script( 'jquery' );


    //Register custom jQuery library
    //wp_register_script( 'jquery', get_template_directory_uri() . '/assets/js/libs/jquery.3.4.1.min.js', false, null, false ); 
    wp_register_script( 'jquery', 'https://code.jquery.com/jquery-3.4.1.min.js', false, null, false ); 


    //Enqueue custom jQuery library
    wp_enqueue_script('jquery');


    //Enqueue LazyLoad
    wp_enqueue_script( 'lazyload', get_template_directory_uri() . '/assets/js/plugins/jquery.lazy.min.js', 'jquery', null, true ); //Depends on jQuery


    //Inline LazyLoad script
    /*
        New LazyLoad instance 
        More info: http://jquery.eisbehr.de/lazy/

        Config:
            scrollDirection: 'vertical',
            effect: 'fadeIn',
            effectTime: 200,
            threshold: 0,
            visibleOnly: true,
            onError: function(element) {
                console.log('jQuery LazyLoad error. Cannnot load: ' + element.data('src'));
            }
    */
    wp_add_inline_script( 'lazyload', "jQuery(function($) {  $('.lazy').Lazy({  scrollDirection: 'vertical', effect: 'fadeIn', effectTime: 200, threshold: 0, visibleOnly: true, onError: function(element) { console.log('jQuery LazyLoad error. Cannnot load: ' + element.data('src')); }  }); });", 'after' );
}

Step 3: Add functions for Image and Background images

Also, within your functions.php add these functions which are used to add the required tags for the Image and Background image tags.

For Images add:

/*
    Image lazyload
    More info: More info: http://jquery.eisbehr.de/lazy/
    ==============================================================================
*/
function filter_lazyload_img($content) {
    return preg_replace_callback('/(<\s*img[^>]+)(src\s*=\s*"[^"]+")([^>]+>)/i', 'preg_lazyload_img', $content);
}
add_filter('the_content', 'filter_lazyload_img');

function preg_lazyload_img($img_match) {
    //Replace the image source with lazy placeholder and add a custom attribute
    $img_replace = $img_match[1] . 'src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" data-src' . substr($img_match[2], 3) . $img_match[3];

    //Add 'lazy' to the class
    $img_replace = preg_replace('/class\s*=\s*"/i', 'class="lazy ', $img_replace);

    //Add a no-script tag of the original element
    $img_replace .= '<noscript>' . $img_match[0] . '</noscript>';
    return $img_replace;
}

And background images, add:

/*
    Background image lazyload
*/
function filter_lazyload_bg($content) {
    //Find the first '<div style="">' element
    //return preg_replace_callback('/(<\s*div[^>]+)(style\s*=\s*"[^"]+")(>)/i', 'preg_lazyload_bg', $content);
    return preg_replace_callback('/(<\s*[^>]+)(style\s*=\s*"[^"]+")(>)/i', 'preg_lazyload_bg', $content);
}
add_filter('the_content', 'filter_lazyload_bg');

function preg_lazyload_bg($div_match) {
    //Replace the div bg image source with lazy placeholder and add a custom attribute
    //Remove white space from style tag, remove "'", remove 28 characters (style="background-image: url() and remove ');"'
    $div_replace = $div_match[1] . 'data-src="' . str_replace(');"', '',  substr(  str_replace("'", '',  str_replace(' ', '', $div_match[2])  ),  28)  ) . '"' . $div_match[3];

    //Add 'lazy' to the class
    $div_replace = preg_replace('/class\s*=\s*"/i', 'class="lazy ', $div_replace);

    //Add a no-script tag of the original element
    //$div_replace .= '</div><noscript>' . $div_match[0] . '</noscript>';

    return $div_replace;
}

Discuss on X (Twitter)