January 17, 2019
bLazy, Echo.js, Yet Another Lazy Loader, jQuery / Wordpress plugins are some of the many libraries designed to speed up initial load, reduce data usage, lighten server load as well as provide a host of other benefits resulting from a site not attempting to call and display every image, script, add-on, iframe (wherever they may be in the page) before it renders itself.
However, for many sites that are running with a hodgepodge of often un-updated and conflicting JavaScript libraries, installing and implementing a library lazy load doesn’t work. Sometimes it’s unresponsive or glitchy and when neither, it just doesn’t run altogether. And anyway, for a site owner that spent the last few days compressing, deleting, combining script / style files to reduce resource requests, calling yet another additional library doesn’t quite have the kick.
Recently I’ve had to optimize the initial load speed of a client’s site via front-end. The site mainly loaded images and iframes. Apart from three images, the rest of these were not in the initial window viewport. Some were nearly at the end of the 3000px-long site, but were being loaded before the site could display.
$('.llazy[data-loaded="false"]').each(function() {
var llazy = $(this);
//...
});
The images / iframes are given the class llazy
, their src
switched to data-src
and an attribute data-loaded
is set to false
. To prevent the structure of the site from collapsing, the initial src
of the images is set to a gray ~1KB placeholder SVG (with the same width-height ratio of the images). The iframes already had fixed heights.
llazy[0].getBoundingClientRect().top - window.innerHeight < 0
The above code was written before I discovered the IntersectionObserver, but I suppose since the site doesn’t scroll horizontally, it will do for now. You could change the zero of course to say 50 or 200 or whatever and the images / iframes would load when they and the user’s viewport have that much (or less than that much) of distance before it appears on screen.
jQuery.noConflict();
window.addEventListener("scroll", function() {
jQuery('.llazy[data-loaded="false"]').each(function() {
var llazy = jQuery(this);
if (llazy[0].getBoundingClientRect().top - window.innerHeight < 0) {
jQuery(this).attr("data-loaded", "true");
jQuery(this).attr("src", jQuery(this).attr("data-src"));
}
});
});
Mootools and jQuery were present, hence the .noConflict()
.
I will be working on those cons time to time but till then, here’s the live demo.
See the Pen A Really Simple Lazy Load - Images & IFrames by Leena Lavanya (@leenalavanya) on CodePen.