lazysizes
lazysizes is a fast (jank-free), SEO-friendly and self-initializing lazyloader for images (including responsive images picture/srcset), iframes, scripts/widgets and much more. It also prioritizes resources by differentiating between crucial in view and near view elements to make perceived performance even faster.
It may become also your number one tool to integrate responsive images. It can automatically calculate the sizes attribute for your responsive images, it allows you to share media queries for your media attributes with your CSS, helping to separate layout (CSS) from content/structure (HTML) and it makes integrating responsive images into any environment really simple. It also includes a set of optional plugins to further extend its functionality.
How to
-
Download the lazysizes.min.js script and include lazysizes in your webpage. (Or install via npm:
npm install lazysizes --saveor bowerbower install lazysizes --save)<script src="lazysizes.min.js" async=""></script>Or:
import 'lazysizes'; // import a plugin import 'lazysizes/plugins/parent-fit/ls.parent-fit'; // Note: Never import/require the *.min.js files from the npm package.Note: For more information see here.
-
lazysizes does not need any JS configuration: Add the
class"lazyload"to your images/iframes in conjunction with adata-srcand/ordata-srcsetattribute. Optionally you can also add asrcattribute with a low quality image:<!-- non-responsive: --> <img data-src="image.jpg" class="lazyload" /><!-- responsive example with automatic sizes calculation: --> <img data-sizes="auto" data-src="image2.jpg" data-srcset="image1.jpg 300w, image2.jpg 600w, image3.jpg 900w" class="lazyload" /><!-- iframe example --> <iframe frameborder="0" class="lazyload" allowfullscreen="" data-src="//www.youtube.com/embed/ZfV-aYdU4uE"> </iframe>
Demo with code examples
Can be seen here
Responsive image support (picture and/or srcset)
Lazysizes is built upon the Responsive image standard and extends it with additional functionality. For full cross browser responsive image support you must use either a full polyfill like picturefill or use the extreme lightweight partial respimg polyfill plugin or the responsive image on demand plugin. Alternatively, you can simply define a fallback src via the data-src attribute. If you want to learn more about the responsive image syntax read "The anatomy of responsive images".
What makes lazysizes so awesome:
lazysizes is different than other lazy image loaders.
- Detects any visibility changes on current and future lazyload elements in any web environment automatically: The script works as an universal, self-initializing, self-configuring and self-destroying component and detects any changes to the visibility of any current and future image/iframe elements automatically no matter whether it becomes visible through a user scroll, a CSS animation triggered through
:hoveror through any kind of JS behavior (carousel, slider, infinite scroll, masonry, isotope/filtering/sorting, AJAX, SPAs...). It also works automatically in conjunction with any kind of JS-/CSS-/Frontend-Framework (jQuery mobile, Bootstrap, Backbone, Angular, React, Ember (see also the attrchange/re-initialization extension)). - Future-proof: It directly includes standard responsive image support (
pictureandsrcset) - Separation of concerns: For responsive image support it adds an automatic
sizescalculation as also alias names for media queries feature. There is also no JS change needed if you add a scrollable container with CSS (overflow: auto) or create a mega menu containing images. - Performance: It's based on highly efficient, best practice code (runtime and network) to work jank-free at 60fps and can be used with hundreds of images/iframes on CSS and JS-heavy pages or webapps.
- Extendable: It provides JS and CSS hooks to extend lazysizes with any kind of lazy loading, lazy instantiation, in view callbacks or effects (see also the available plugins/snippets).
- Intelligent prefetch/Intelligent resource prioritization: lazysizes prefetches/preloads near the view assets to improve user experience, but only while the browser network is idling (see also
expand,expFactorandloadModeoptions). This way in view elements are loaded faster and near of view images are preloaded lazily before they come into view. - Lightweight, but mature solution: lazysizes has the right balance between a lightweight and a fast, reliable solution
- SEO improved: lazysizes does not hide images/assets from Google. No matter what markup pattern you use. Google doesn't scroll/interact with your website. lazysizes detects, whether the user agent is capable to scroll and if not, reveals all images instantly.
More about the API
lazysizes comes with a simple markup and JS API. Normally you will only need to use the markup API.
Markup API
Add the class lazyload to all img and iframe elements, which should be loaded lazy. Instead of a src or srcset attribute use a data-src or data-srcset attribute:
<img data-src="image.jpg" class="lazyload" />
<!-- retina optimized image: -->
<img data-srcset="responsive-image1.jpg 1x, responsive-image2.jpg 2x" class="lazyload" />
Automatically setting the sizes attribute
lazysizes supports setting the sizes attribute automatically, corresponding to the current size of your image - just set the value of data-sizes to auto.
<img
data-sizes="auto"
data-srcset="responsive-image1.jpg 300w,
responsive-image2.jpg 600w,
responsive-image3.jpg 900w"
class="lazyload" />
Important: How sizes is calculated: The automatic sizes calculation uses the display width of the image. This means that the width of the image has to be calculable at least approximately before the image itself is loaded (This means you can not use width: auto). Often the following general CSS rule might help: img[data-sizes="auto"] { display: block; width: 100%; } (see also specifying image/iframe dimensions with the recommended aspect ratio definition). If it is below 40 (can be configured through the minSize option), lazysizes traverses up the DOM tree until it finds a parent which is over 40 and uses this number.
The width auto-calculated by lazysizes can be modified using the lazybeforesizes event (lazybeforesizes documentation). Alternatively, the parent fit plugin can be used for sizing images to fit a parent / container, and is the only solution when an image's height needs to be taken into account when fitting it to its container (This also includes the use of object-fit).
The data-sizes="auto" feature only makes sense if you use the data-srcset attribute with width descriptors which allows the most appropriate image can be selected (It does not make sense if you use the x descriptor or only src.).
Recommended/possible markup patterns
lazysizes allows you to write an endless variety of different markup patterns. Find your own/best pattern or choose one of the following. (All of the following patterns can be also used for art direction using the picture element.)
Simple pattern
Add the class lazyload and simply omit the src attribute or add a data uri as fallback src.
<!-- responsive adaptive example -->
<img
class="lazyload"
data-srcset="image.jpg 1x, image2.jpg 2x"
alt="my image" />
<!-- retina optimized example -->
<img class="lazyload"
data-srcset="progressive-image.jpg 1x, progressive-image2.jpg 2x"
alt="my image" />
<!-- or non-responsive: -->
<img
data-src="image.jpg"
class="lazyload" />
Note: In case you are using either srcset/data-srcset or picture, we recommend to extend this pattern with either a data-src (see next pattern: "Combine data-srcset with data-src") or with a suitable src attribute (see: "modern pattern" or "LQIP").
Combine data-srcset with data-src
In case you want to use responsive images for supporting browsers, but don't want to include a polyfill, simply combine your data-srcset with a data-src attribute.
<!-- responsive example: -->
<img
data-sizes="auto"
data-src="image3.jpg"
data-srcset="image3.jpg 600w,
image1.jpg 220w,
image2.jpg 300w,
image3.jpg 600w,
image4.jpg 900w"
class="lazyload" />
Note: Due to the fact that the data-src will also be picked up by "Read-Later" Apps and other tools (for example Pin it button), this pattern also makes sense if you use a polyfill. In case you don't use a polyfill it is recommended that the first image candidate matches the fallback src.
LQIP/blurry image placeholder/Blur up image technique
If you are using the LQIP (Low Quality Image Placeholder) pattern, simply add a low quality image as the src:
<!-- responsive example: -->
<img
data-sizes="auto"
src="lqip-src.jpg"
data-srcset="lqip-src.jpg 220w,
image2.jpg 300w,
image3.jpg 600w,
image4.jpg 900w" class="lazyload" />
<!-- or non-responsive: -->
<img src="lqip-src.jpg" data-src="image.jpg" class="lazyload" />
The LQIP technique can be enhanced by combining it with CSS transitions/animation to sharpen/unblur or overfade the LQIP image.
Please also have a look at our lazysizes Blur Up plugin (recommended).
<style>
.blur-up {
-webkit-filter: blur(5px);
filter: blur(5px);
transition: filter 400ms, -webkit-filter 400ms;
}
.blur-up.lazyloaded {
-webkit-filter: blur(0);
filter: blur(0);
}
</style>
<img src="lqip-src.jpg" data-src="image.jpg" class="lazyload blur-up" />
<!-- ... -->
<style>
.fade-box .lazyload,
.fade-box .lazyloading {
opacity: 0;
transition: opacity 400ms;
}
.fade-box img.lazyloaded {
opacity: 1;
}
</style>
<div class="ratio-box fade-box">
<img src="lqip-src.jpg" />
<img data-src="image.jpg" class="lazyload" />
</div>
modern transparent srcset pattern
Combine a normal src attribute with a transparent or low quality image as srcset value and a data-srcset attribute. This way modern browsers will lazy load without loading the src attribute and all others will simply fallback to the initial src attribute (without lazyload). (This nice pattern originated from @ivopetkov.)
<img
src="image3.jpg"
srcset="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
data-srcset="image3.jpg 600w,
image1.jpg 220w,
image2.jpg 300w,
image4.jpg 900w"
data-sizes="auto"
class="lazyload" />
The noscript pattern
In case disabled JavaScript is a concern you can combine this simple pattern with an image inside a noscript element.
<style>
.no-js img.lazyload {
display: none;
}
</style>
<!-- noscript pattern -->
<noscript>
<img src="image.jpg" />
</noscript>
<img src="transparent.jpg" data-src="image.jpg" class="lazyload" />
Note: As an alternative to the noscript pattern also checkout the noscript extension.
[data-expand] attribute
Normally lazysizes will expand the viewport area to lazy preload images/iframes which might become visible soon. This value can be adjusted using the expand option.
Additionally, this general option can be overridden with the data-expand attribute for each element. Different than the general expand option the data-expand attribute also accepts negative values (All numbers but 0 are accepted!).
This becomes especially handy to add unveiling effects for teasers or other elements:
<style>
.lazyload,
.lazyloading {
opacity: 0;
}
.lazyloaded {
opacity: 1;
transition: opacity 300ms;
}
</style>
<div class="teaser lazyload" data-expand="-20">
<img data-src="image.jpg" class="lazyload" />
<h1>Teaser Title</h1>
<p>...</p>
</div>
CSS API
lazysizes adds the class lazyloading while the images are loading and the class lazyloaded as soon as the image is loaded. This can be used to add unveil effects:
/* fade image in after load */
.lazyload,
.lazyloading {
opacity: 0;
}
.lazyloaded {
opacity: 1;
transition: opacity 300ms;
}
/* fade image in while loading and show a spinner as background image (good for progressive images) */
.lazyload {
opacity: 0;
}
.lazyloading {
opacity: 1;
transition: opacity 300ms;
background: #f7f7f7 url(loader.gif) no-repeat center;
}
Broken image symbol
In case you are using an alt attribute but do not declare a src/srcset attribute you will end up with a broken image symbol.
There are two easy ways to deal with it.
Either define a src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" or add the following CSS.
img.lazyload:not([src]) {
visibility: hidden;
}
JS API
lazysizes automatically detects new elements with the class lazyload so you won't need to call or configure anything in most situations.
JS API - options
Options can be set by declaring a global configuration option object named lazySizesConfig. This object must be defined before the lazysizes script. A basic example:
window.lazySizesConfig = window.lazySizesConfig