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 --save
or 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-src
and/ordata-srcset
attribute. Optionally you can also add asrc
attribute 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
:hover
or 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 (
picture
andsrcset
) - Separation of concerns: For responsive image support it adds an automatic
sizes
calculation 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
,expFactor
andloadMode
options). 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