Posted over 2 years ago. Visible to the public. Repeats.

Lazy-loading images

Since images are magnitudes larger in file size than text (HTML, CSS, Javascript) is, loading the images of a large web page takes a significant amount of the total load time. When your internet connection is good, this is usually not an issue. However, users with limited bandwidth (i.e. on mobile) need to mine their data budget better.

One popular strategy to improve the website performance is to not load images until they enter the viewport – aka "lazy-loading images".

General Issues

  • Crawlers do not execute JavaScript (generally speaking). When removing the src attribute of an img tag in favor of lazy-loading, make sure you have a strategy to serve crawlers, if you need to support them.
  • When the lazy-loaded image in inserted into the page, it may push other elements down to get the space it needs. Prevent a jumpy user experience by giving the image container the dimensions of the image.
  • Mobile devices usually trigger the onscroll event only when the "momentum scroll" has ended. This way you may coast into parts of the page where images have not been loaded yet (depending on the library). (Starting from iOS 8, continuous scroll events are fired.)

Suggested Library

Lazysizes is one of the most popular lazy-loading libraries, and it seems to be unsurpassed in any regard. See the README to understand the full power of it. Here are some examples.

Features:

  • it automatically notices when images should be loaded, thus it works with sliders, lightboxes and almost anything; this feature is really amazing and makes this library stand apart from others. It is achieved by registering to a dozen events plus using a MutationObserver, if available.
  • the author seems to be really eager to maintain the library
  • it requires no configuration (just include it to your page), but offers a powerful API
  • it was written to be performant, with little runtime as well as memory consumption; it promises to be jank-free, rendering at 60fps
  • it features a plugin system, bringing 14 plugins out of the box
    • noscript plugin: support for non-JS browsers, i.e. crawlers

Hints:

  • If you need to react on image load, e.g. to update some slider layout, just listen for the event:

    Copy
    $('.some-element').get(0).addEventListener('load', yourCallBack, true);

    The final true registers the listener to the "capturing phase" (as opposed to the "bubbling phase"). This is because the load event does not bubble. Note that you cannot register an event listener via jQuery, as it does not support capturing events. That's why that get(0) is there.

JS-only: not working

The "best" strategy would be to hide the src attribute of image tags from the browser with JS. This way, no modification of the HTML would be necessary and the whole lazy-loading could be accomplished by javascript. However, this does not work reliably. Qazy is a library that implements this approach, and it is working on their demo page. However, on a large page in my application, Qazy came too late to keep the browser from loading images.

About crawlers

All working lazy-load strategies require the src attribute of images to be removed (see above). Filling it back in via JS is ok for most users, but crawlers won't see your images. One approach is to render the image a second time into a noscript tag. This is quite straightforward and most people on the web agree that it won't negatively influence SEO ranking.

Another approach is to render image links instead of tags, and then replace all image links with tags via javascript. I did not further investigate this method because I did not want to rebuild the whole application. When building an application with this approach from the ground up, it might be a valid option.

makandra has been working exclusively with Ruby on Rails since 2007. Our laser focus on a single technology has made us a leader in this space.

Author of this card:

Avatar
Dominik Schöler
Last edit:
16 days ago
by Michael Leimstädtner
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Dominik Schöler to makandra dev