Lazy loading images with Intersection Observer
/**
* A simple demo on how the new Intersection Observer API can be used to lazy load images.
* https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
*
* Intersection Observer is available in most modern browsers and there's a decent polyfill, too:
* https://github.com/WICG/IntersectionObserver/tree/gh-pages/polyfill
*/
let imageNodes = [];
// generate some test image
for ( let i = 0; i < 1000; i++ ) {
let image = document.createElement( 'img' );
image.setAttribute( 'data-src', 'https://api.adorable.io/avatars/285/' + i ); // Note: Not using `src` here.
document.body.appendChild( image );
imageNodes.push( image );
}
const intersectionObserver = new IntersectionObserver(
onIntersectionObservation,
{ rootMargin: '0px 0px 1000px 0px' } // preload all images that are in the viewport and 1000px below "the fold".
);
imageNodes.forEach( ( imageNode ) => intersectionObserver.observe( imageNode ) );
function onIntersectionObservation( entries, observer ) {
entries
.filter( ( entry ) => entry.target.hasAttribute( 'data-src' ) && entry.isIntersecting )
.forEach( ( entry ) => {
// swap data-src and src
entry.target.setAttribute( 'src', entry.target.getAttribute( 'data-src' ) );
entry.target.removeAttribute( 'data-src' );
observer.unobserve( entry.target );
} )
;
}