Elements loaded


Speed up your responsive and retina-aware website with LaziestLoader, a jQuery plugin that loads, from an array of sources, the most appropriate image at the last possible moment, and updates the image after a resize if needed. Custom callbacks and configuration provide even more functionality, like loading non-image elements and generic scroll-based triggers.

Download v0.7.2

  1. Development Version
  2. Production Version
  3. $ npm install laziestloader
  4. $ bower install laziestloader

Image Prep

Your web-ready files need to be structured so that the name or path includes the width or a slug that represents the width.


    • /images/pony-1300.jpg
    • /images/pony-900.jpg
    • /images/pony-640.jpg
    • /images/pony/1300.jpg
    • /images/pony/900.jpg
    • /images/pony/640.jpg
    • /images/1300/PONY-1300.jpg
    • /images/900/PONY-900.jpg
    • /images/640/PONY-640.jpg
    • /images/pony-large.jpg
    • /images/pony-medium.jpg
    • /images/pony-small.jpg
    • /images/pony/large.jpg
    • /images/pony/medium.jpg
    • /images/pony/small.jpg


Retina images are also supported with either pattern. You can use whatever naming convention you like to specify the retina source.

    • /images/pony-1300@2x.jpg
    • /images/pony-900@2x.jpg
    • /images/pony-640@2x.jpg
    • /images/retina-large/pony.jpg
    • /images/retina-medium/pony.jpg
    • /images/retina-small/pony.jpg


Your image element should include a default image. A 1px transparent png or gif will work fine. You may also want to add a class to simplify your jQuery selector in a moment.

<img class="lazy" src="img/transparent.gif">

LaziestLoader works by finding the best-sized source image to match the target image element's current width. Since "img" elements are inline elements, they'll only have as much width at the current image, which will most likely be very small, like a 1px transparent gif. To ensure the plugin works correctly, you need to make sure the "img" element reports the width you want it to be. One way is to force it to fill its container element with CSS.

img.lazy{ display:block; width: 100%; }

Example Usage


The most basic method simply sets the src attribute as the element enters the viewport.

// html
<img class="lazy" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/753e75/fff.png">

// js

Non-responsive w/ Retina

Specify a standard and an optional retina image.

// html
<img class="lazy" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/2a2a2a/fff.png" data-src-retina="http://dummyimage.com/2800x1400/2a2a2a/fff.png">

// js

Non-responsive w/ Retina, smaller element

Basic example always loads the same image, regardess of element width.

// html
<img class="lazy" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/3a3a3a/fff.png" data-src-retina="http://dummyimage.com/2800x1400/3a3a3a/fff.png">

// js


Go beyond a single source by providing a URL that has a width as part of the path or name.

// html
<img class="lazy" src="img/transparent.gif" data-pattern="img/ar-{{size}}.jpg" data-widths="[320, 900, 1500]">

// js

Responsive, smaller element

Load a smaller image, if possible.

// html
<img class="lazy" src="img/transparent.gif" data-pattern="img/ar-{{size}}.jpg" data-widths="[320, 900, 1500]">

// js

Responsive w/ Slugs

You can select a sized image that doesn't use the width value in the file name or path.

// html
<img class="lazy" src="img/transparent.gif" data-pattern="img/ar2-{{size}}.jpg" data-widths='[{"size":320,"slug":"small"}, {"size":900, "slug":"medium"}, {"size":1500, "slug":"large"}]'>

// js


Pass in a callback to excute custom code after the src attribute has been changed. That's how the updating "elements loaded" bar below works.

<img class="callback" src="img/transparent.gif" data-src="http://dummyimage.com/1400x700/5a5a5a/fff.png">

// js
var totalLoaded = 0;
$("img.callback").laziestloader({ threshold: 100}, function() {
    totalLoaded += 1;

Custom Source Function

Need fancier logic to determine the source path? You can write your own.

<img class="custom" src="img/transparent.gif">

// js
    threshold: 100,
    getSource: function($el) {
        var width = $el.width();
        var height = Math.round(width * 0.5625);
        return 'http://placekitten.com/'+width+'/'+height;

Best Fit

The best-fit method used internally can also be used in your callbacks and custom source functions. Pass in a target width and an array of possible values to find the best value.

<img class="bestfit" src="img/transparent.gif">

// js
    threshold: 100,
    getSource: function($el) {
        var width = $().laziestloader.bestFit($el.width(), [200, 700, 900, 1200]);
        var height = Math.round(width * 0.5625);
        return 'http://placekitten.com/'+width+'/'+height;


Images aren't the only things with 'src' attributes. Try a video.

// html
<video class="lazy" autoplay loop data-pattern="http://joshwilliams.com/projects/sunset-flipbook/videos/bridge-{{size}}.mp4" data-widths="[640, 900]"></video>

// js

Set Element Height Programmatically

Often in responsive applications it's useful to set the height of an element before the source is loaded so the element will pre-fill the correct amount of space. In this example, because iFrames also have src attributes but need their sizes specified to be useful, we'll set the height via the plugin. The height is determined by multipling the element width by the 'data-ratio' vaule. Note: This example will not be responsive because the iFrame content from YouTube isn't smart enough to repsond to the changing viewport.

// html
<iframe class="iframe" data-src="//www.youtube.com/embed/fNlxKH9Jtmc" data-ratio="0.5625" frameborder="0" allowfullscreen></iframe>

// js

Completely Custom Behavior /w Callback

Need more control than custom source path generation? For example, you might want to completely rewrite the contents of your element. You can have your callback do all the work, sidestepping much of LaziestLoader's functionality.

// html
<div class="override"></div>

// js
    threshold: 100,
    setSourceMode: false // this is the important bit!
}, function(){
    var height = Math.round($(this).width() * 0.5625);
    $(this).html('<p style="text-align:center; height: '+height+'px; line-height:'+height+'px;-webkit-animation: pulse 10s infinite alternate;">Boom!</p>')


In addition to the "Custom Source Function" using `getSource` example above, there are other optional behaviors that can be configured in the options object.


By default, images are only loaded when the user scrolls to them and they became visible on the screen.

If you want your images to load earlier than that, lets say 200px before they appear on the screen, specify the threshold in the options object.

$("img").laziestloader({threshold: 200});


To increase performance, the position of lazy loading elements are only checked every 250ms while scrolling. If you need to perform the check more often, lower the number. If scroll performance is an issue -- likely if there are lots of elements -- increase the number.

$("img").laziestloader({scrollThrottle: 300});


The crop selection logic works by picking the image that is greater than or equal to the size of the current element. If you prefer to scale smaller images into larger elements, set this between 0 and 100, where the value is the percent width of the containing element you want to subtract from the math logic. The bigger the number, the smaller the image that'll be selected.

$("img").laziestloader({sizeOffsetPercent: 10});


The regular expression used to search your string, to be replaced by the width number or slug. The default is `/{{SIZE}}/ig`, which finds the string `size`, regardless of case, inside of '{' style double brackets. Example: `/path/name-{{size}}.jpg`. Changing this option is useful if, for example, you have Mustache-style templates rendered on the server that would also match the default laziestloader.js pattern and be rendered blank before our client code runs. Many characters have special meaning and can't be used. A nice alternal pattern is:

$("img").laziestloader({sizePattern: /%size%/ig});


In most cases, the plugin needs to set the source attribute of the element. If you want to use the plugin in ways that don't involve simply setting a source attribute, set `setSourceMode` to false and use the callback to completely manage the behavior of the element on trigger.

<div><p>Replace me</p></div>

    setSourceMode: false
}, function(){
    $(this).html('<div><p>New content</p></div>')


You can trigger element loading without scrolling the element into view.


Release History





















LaziestLoader is by Josh Williams. Inspried by Luís Almeida's unveil


LaziestLoader is licensed under the MIT license

Fork me on GitHub