Peekaboo Image Lazyload Demo

Using Peekaboo to lazyload your nice responsive images. View the page source to see the gritty details.

HTML Markup

The demo was written with the following markup in mind:

<img src="/path/to/small/lowres/version.jpg"
     srcset="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
     data-srcset="the actual required srcset declaration"
     alt="Alt text" />
The markup used for the images within the demo

The whys and the hows…

src

The src attribute value is set to point to a lowres version of the image, served to browsers that do not take the srcset attribute into account.

srcset

The srcset attribute value is set to a base64 encoded transparent gif. This will be used as a placeholder for more modern browsers that do take the srcset attribute into account.

data-srcset

The real srcset declaration is then defined within the data-srcset data attribute.

The big reveal

Whenever the script determines the image has passed the display threshold (under 100 pixels away from the viewport in this demo), the callback function is fired which updates the image srcset attribute to be the value of the data-srcset attribute, forcing the browser to choose and download one of the images listed in the new srcset declaration. The data-srcset attribute is then removed completely.

The fade-in effect

Each image passed to the callback function is given the classname lazyloaded which sets the opacity to 0. An onload event handler is set on the document that catches the image load event and removes the lazyloaded classname. This transitions the image to full opacity and provides the fade-in effect.

This is entirely optional and has nothing really to do with the lazyloading – I just thought it made the demo look better.

Demo

A simple demo that lazyloads 50 images as they scroll into view is shown below:

peekaboo.observe({
    "pattern": "img[data-srcset]",
    "callback": function(imageList) {
        imageList.forEach(function(elem) {
            elem.classList.add("lazyloaded");
            elem.setAttribute("srcset", elem.getAttribute("data-srcset"));
            elem.removeAttribute("data-srcset");
        });
    },
    "fastVisibilityCheck": true,
    "rootMargin": 100
});
A stripped down version of the demo source code