DIY Lazy Load

← back to the blog

I am constantly looking for practical ways to get all the beautiful images in a design to load without hampering the page load unreasonably. While responsive images have been the biggest help, occasionally something else is called for.

For example, the content of carousel slides that are initially invisible can be deferred until the rest of the page has loaded, and the carousel can be started manually only once all the images are obtained. This lets the page load fast, and defers requests for images that aren't visible anyway. The user's experience is "enhanced" by starting the carousel once all the required content has been obtained.

How to implement this? While there are several lazy loading plugins available, most of them are based on scrolling which doesn't match our use case. What I came up with was the following:


(function($) {
  $.fn.deferImageLoading = function(callback) {
    var group = this;
    var count = this.length;

    return this.each(function() {
      var $img = $(this);
      $(window).load(function() {
        $img.attr('src', $img.data('src')).load(function() {
          count--;
          if (!count && $.isFunction(callback)) {
              callback.call(group);
          }
        });
      });
    });

  };
}(jQuery));

This JQuery method will take every selected element, and after the page has fully loaded, replace the src attribute with the data-src attribute, effectively spurring image loading or replacing a low-resolution image with a high-resolution one.

<img src="#" data-src="high-res.png" class="defer" />
$('.defer').deferImageLoading(function() {
  // start the carousel (or whatever)
});

To enhance this even further, all the controls to access deferred images can be hidden until the callback is called.