Advertisement

#19 Lazy Loading Images

In this article we will see how to lazy load all of our image tags. The process will be to add a small npm package to our project and then to update our image tags. The updating is extremely simple and basically boils down to adding a css class and coverting any srcset and src attributes to be data dashed. As we will see this will work for all of our images regardless of whether we are solving either the resolution switching or art direction problems.

Example UI

  • WebUi
    • Pages
      • Responsive-Images.cshtml

We will just start off by creating all the underlying code for the examples that we will be showing in this article (a). Our goal is to take all of the previous examples and show how to accomplish them while adding lazy loading of our images into the equation.

Responsive-Images.cshtml

...
<nav class="responsive-image-nav">
    <label>Problems</label>
    ...
    <a class="@( Model.Problem == "lazy-loading" ? "active" : "" )"
       href="/responsive-images?problem=lazy-loading&query=off">Lazy Loading</a>
</nav>
...
else if (Model.Problem == "lazy-loading")
{
    <nav class="responsive-image-nav lazy-loading-nav">
        <label>Lazy</label>
        <a class="@( Model.Query == "off" ? "active" : "" )"
           href="/responsive-images?problem=lazy-loading&query=off">Off</a>
        <a class="@( Model.Query == "non-responsive" ? "active" : "" )"
           href="/responsive-images?problem=lazy-loading&query=non-responsive">Non-Responsive</a>
        <a class="@( Model.Query == "different-sizes" ? "active" : "" )"
           href="/responsive-images?problem=lazy-loading&query=different-sizes">Different Sizes</a>
        <a class="@( Model.Query == "same-size" ? "active" : "" )"
           href="/responsive-images?problem=lazy-loading&query=same-size">Same Size</a>
        <a class="@( Model.Query == "picture" ? "active" : "" )" 
           href="/responsive-images?problem=lazy-loading&query=picture">Picture</a>
    </nav>

    if (Model.Query == "off")
    {
        for(var i = 1; i <= 10; i++)
        {
            
        }
    }
    else if (Model.Query == "non-responsive")
    {
        for(var i = 1; i <= 10; i++)
        {
            
        }
    }
    else if (Model.Query == "different-sizes")
    {
        for(var i = 1; i <= 10; i++)
        {
            
        }
    }
    else if (Model.Query == "same-size")
    {
        for(var i = 1; i <= 10; i++)
        {
            
        }
    }
    else if (Model.Query == "picture")
    {
        for(var i = 1; i <= 10; i++)
        {
            
        }
    }
}
(a) Just the prep code for making our job easier showing how to convert everything to lazy loading of the images.

Back to npm

  • WebUi
    • package.json

To accomplish the lazy loading of our images we are going to make use of an npm package called lazysizes . To add the package we just need to use the command shown in (b) which at the time of the writing of this article will install the package with the version number shown in (c)

Terminal

npm install --save-dev lazysizes
(b) Command used to install the package that we are going to make use of for adding the ability to lazy load images to our pages.

package.json

{
    ...
    "devDependencies": {
        ...,
        "lazysizes": "^4.1.4",
        ...
    }
}
(c) The version number of lazysizes at the time of the writing of this article.

Add lazysizes to our pages

  • WebUi
    • Source
      • main.page.ts

Now that the package has been downloaded we need to add it to all of our pages. The easiest way to do this is to add it in our main page typescript file (d).

main.page.ts

...
require("lazysizes");
...
(d) Adding the require call to our main page typescript file will make sure that we can lazy load an image on any page.

First off no lazy loading

  • WebUi
    • Pages
      • Responsive-Images.cshtml

We will start by seeing how the browser reacts to the inclusion of 10 image tags without any lazy loading functionality being used (e). If we check the network tab as expected all of the images will be loaded on page load regardless of whether or not they are in or near the viewport of the device.

Responsive-Images.cshtml

...
else if (Model.Problem == "lazy-loading")
{
    ...
    if (Model.Query == "off")
    {
        for(var i = 1; i <= 10; i++)
        {
            <div class="image-container">
                <img src="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-320w.jpg"
                     alt="Woman sitting on a chair beside a balloon">
                <div class="image-caption">
                    <p>Photo by Daria Shevtsova from Pexels</p>
                    <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
                </div>
            </div>
        }
    }
}
(e) Initial test to show that all images are downloaded when the page loads regardless of their position on the page relative to the device viewport.
Advertisement

Lazy loading a standard image tag

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Next up we will simply take the image tags that we were loading in the previous example and modify them in such a way to cause lazysizes to lazy load them (f). In this case we just need to add a css class to the image and change the src attribute to data-src. Once those two changes are made lazysizes will take care of requesting the images when/if the user scrolls the page.

Responsive-Images.cshtml

...
else if (Model.Problem == "lazy-loading")
{
    ...
    else if (Model.Query == "non-responsive")
    {
        for(var i = 1; i <= 10; i++)
        {
            <div class="image-container">
                <img class="lazyload"
                     data-src="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-320w.jpg"
                     alt="Woman sitting on a chair beside a balloon">
                <div class="image-caption">
                    <p>Photo by Daria Shevtsova from Pexels</p>
                    <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
                </div>
            </div>
        }
    }
}
(f) Just two changes are all that we need to convert our images to being lazy loaded.

Different Sizes

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Adding lazy loading to any of our image tags that are showing the same image at different resolutions is just about as easy except we have three minor changes to make instead of two (g). The changes we make are to add the css class, change the srcset attribute to data-srcset and change the src attribute to data-src.

Responsive-Images.cshtml

...
else if (Model.Problem == "lazy-loading")
{
    ...
    else if (Model.Query == "different-sizes")
    {
        for(var i = 1; i <= 10; i++)
        {
            <div class="image-container">
                <img class="lazyload" 
                     data-srcset="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-320w.jpg 320w,
                                  /images/responsive-images/woman-balloon-chair-dark-Copy@(i)-480w.jpg 480w,
                                  /images/responsive-images/woman-balloon-chair-dark-Copy@(i)-800w.jpg 800w"
                    sizes="(max-width: 320px) 320px,
                           (max-width: 480px) 480px,
                           800px"
                    data-src="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-800w.jpg"
                    alt="Woman sitting on a chair beside a balloon">
                <div class="image-caption">
                    <p>Photo by Daria Shevtsova from Pexels</p>
                    <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
                </div>
            </div>
        }
    }
}
(g) Just three changes will make it so that any image tag that is displaying the same image based on the resolution of the user device will no be lazy loaded.

Same Size

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Following the pattern the next thing to accomplish is to convert our image tags that serve an image based on the device pixel ratio, DPR, of the user's device to also be lazy loaded (h). In this case the way we do that is the exact same way that we do in the different sizes case by adding the class and changing the srcset and src attributes.

Responsive-Images.cshtml

...
else if (Model.Problem == "lazy-loading")
{
    ...
    else if (Model.Query == "same-size")
    {
        for(var i = 1; i <= 10; i++)
        {
            <div class="image-container same-size">
                <img class="lazyload"
                    data-srcset="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-320w.jpg,
                                 /images/responsive-images/woman-balloon-chair-dark-Copy@(i)-640w.jpg 2x"
                    data-src="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-640w.jpg"
                    alt="Woman sitting on a chair beside a balloon">
                <div class="image-caption">
                    <p>Photo by Daria Shevtsova from Pexels</p>
                    <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
                </div>
            </div>
        }
    }
}
(h) Converting our DPR dependent images to being lazy loaded is exactly the same process as the previous example.

The picture tag

  • WebUi
    • Pages
      • Responsive-Images.cshtml

Last but not least we need to change the contents of our picture tags to be lazy loaded as well. Thankfully it is just the same pattern over and over. We just need to add the css class to the image tag and change any srcset and src attributes to their data dashed counterparts (i).

Responsive-Images.cshtml

...
else if (Model.Problem == "lazy-loading")
{
    ...
    else if (Model.Query == "picture")
    {
        for(var i = 1; i <= 10; i++)
        {
            <div class="image-container">
                <picture>
                    <source media="(max-width: 799px)"
                            data-srcset="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-320w.jpg">
                    <source media="(min-width: 800px)"
                            data-srcset="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-800w.jpg">
                    <img class="lazyload"
                         data-src="/images/responsive-images/woman-balloon-chair-dark-Copy@(i)-800w.jpg"
                         alt="Woman sitting on a chair beside a balloon">
                </picture>
                <div class="image-caption">
                    <p>Photo by Daria Shevtsova from Pexels</p>
                    <p>https://www.pexels.com/photo/woman-sitting-on-chair-beside-balloon-1391580/</p>
                </div>
            </div>
        }
    }
}
(i) Converting the contents of our picture tags follows the same pattern as all the others. Add the css class to the image tag and convert any srcset and src attributes to their data dashed counterparts.
Exciton Interactive LLC
Advertisement