IOLazy Demo
A small JavaScript image lazy loading library based off of Lazy Loading Images with Intersection Observer
Setup
Grab the latest release from io-lazyload releases
Or install it through NPM with npm install iolazyload
Place iolazy.min.js
from dist/js as the last script in the
head of your document.
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- intersection observer polyfill -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
<!-- the iolazy load library -->
<script src="dist/js/iolazy.min.js" defer></script>
</head>
Add the class of lazyload
to the image(s) you wish to lazyload and
modify the src attribute to read data-src
<img data-src="your/image.jpg" alt="your alt text" class="lazyload" >
Initialize the script before the closing body tag (or in your own JS file)
<script>
document.addEventListener("DOMContentLoaded", function () {
new IOlazy();
});
</script>
</body>
Examples
This Is a background image in CSS
Options
There are three (3) options available to pass to IOlazy:
-
image
-
threshold
-
rootMargin
image
This is the class or image element you wish to lazy load.
<!-- lazy load all images with the class 'lazy' -->
<script>
document.addEventListener("DOMContentLoaded", function () {
new IOlazy({
image: '.lazy'
});
});
</script>
<!-- lazy load all image elements -->
<script>
document.addEventListener("DOMContentLoaded", function () {
new IOlazy({
image: 'img'
});
});
</script>
Threshold
How much the image element should be visible before we load the image. Values range from 0 to 1.0. A value
of 1 passed in as a threshold means the image is completely visible in the browser viewport. A value of 0.0
means "any non-zero number of pixels". The Library's default is 0.006
<script>
document.addEventListener("DOMContentLoaded", function () {
new IOlazy({
threshold: 0.8
});
});
</script>
Root Margin
Margin added around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). This set of values serves to grow or shrink each side of the root element's bounding box before computing intersections. Defaults to all zeros.
<script>
document.addEventListener("DOMContentLoaded", function () {
new IOlazy({
rootMargin: "50px 20px"
});
});
</script>
Responsive Images
To lazyload your responsive images using srcset you'll need to prefix your srcset attribute with data-srcset
<img sizes="(min-width: 530px) 25vw, 100vw"
data-srcset="your/image-177w.png 177w,
your/image-240w.png 240w,
your/image-321w.png 321w"
src="your/low/quality/placeholder.png"
alt="Your Alt Text"
class="lazyload" >
Your src
attribute can be as shown above a low quality placeholder or a
1px transparent gif.
If you use a transparent gif or no src attribute you should provide a fallback for browsers that don't use javascript or for instances where the script fails or another script blocks the page.
<style>
/** add display none to the images with the lazyload class */
.no-js img.lazyload {
display: none;
}
</style>
<noscript>
<img src="your/image.png" />
</noscript>
<img sizes="(min-width: 530px) 25vw, 100vw"
data-srcset="your/image-177w.png 177w,
your/image-240w.png 240w,
your/image-321w.png 321w"
src="your/low/quality/placeholder.png"
alt="Your Alt Text"
class="lazyload" >
Browser Support
The lazyload script itself uses classList
which is Internet Explorer 10+. If you have to support lower than that you'll need to use a polyfill (found under 'resources' here) or use the Polyfill service mentioned below under "polyfill".
- Internet Explorer 10+
- Internet Explorer Mobile 10+
- Safari and iOS Safari (chrome included) 6.1+
- Chrome, FireFox, Edge, Opera and all other "modern" browsers
Intersection Observer is supported in these browsers without a polyfill
PolyFill
This demo uses PolyFill.io to supply the polyfill. It's also noted above in the setup portion.
If you don't want to use another third party there is a polyfill provided by the Web Incubator Community Group @ IntersectionObserver Polyfill
The polyfill supports all Firefox, Chrome, Edge, Safari 6+, Internet Explorer 7+. Intersection Observer Polyfill Browser Support
Source
Using Native lazy Load
You can forgo using this library to lazy load images in the instance the the browser supports the "loading" attribute.
You'll need to add the loading
attribute to your each of your image tags in order for this to work properly.
<img sizes="(min-width: 530px) 25vw, 100vw"
data-srcset="your/image-177w.png 177w,
your/image-240w.png 240w,
your/image-321w.png 321w"
src="your/low/quality/placeholder.png"
alt="Your Alt Text"
class="lazyload"
loading="lazy"
>
Once your images have the loading attribute we'll need to add a bit of javascript in your page, or your own javascript bundle/file. How you choose to do this is up to you!
In this file we will query for all the images on our page, grab the data-src
attribute and make that the src
of our image tags. If your page contains responsive images with the "srcset" attribute you'll need to also grab those attributes and apply those as well.
Example of using the native lazy loading instead of this library.
<script>
if ('loading' in HTMLImageElement.prototype) {
// you could also use the class/id you use for the IOLazy library here for the images variable.
const images = document.querySelectorAll("img");
images.forEach(img => {
img.src = img.dataset.src;
// this if clause is only needed if you have __ANY__ images with a srcset attribute.
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
});
}
</script>
You'll need to make a decision here as to how you want to load the IOLazy library - in your bundle, a loader etc. Since there are multiple ways for this to happen I'll show you the dynamically imported version.
<script>
if ('loading' in HTMLImageElement.prototype) {
const images = document.querySelectorAll("img");
images.forEach(img => {
img.src = img.dataset.src;
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
});
} else {
let scriptEl = document.createElement('script');
// set the scripts attribute to 'async'
scriptEl.async = true;
// set the src of the script element to the IOlazy javascript file.
scriptEl.src = './path/to/iolazy.min.js';
// append this newly created script element to the end of the body of our page.
document.body.appendChild(scriptEl);
}
</script>
For a full example of using Native Lazyload see this Using Native Lazyload with IOLazy example page.