Lazy loading images
Posted: October 14, 2013 Filed under: JavaScript Comments Off on Lazy loading imagesThe other day I decided to show a random post from my images blog on my main moranjr.com page. The issue is that because of the number of images, the page was loading slowly so I wrote a lazy loader to the site a faster load even with the random posts.
What the script does is simply to load the images in the post but it only the displays those that are in the current view port. By deferring some heavy image loads, your site will render much quicker if you have a lot of images to show.
There are other requirements too:
- Make it as lean as possible
- Have no JS library dependencies (jQuery or others)
The annotated code is below:
/* A lazy load script with no jQuery dependencies Script by Carlos Moran License MIT */ var ll = function(document, window, soffset, imgs){ var i, // counter for DOM j; // counter for img data array var imgsData = []; // Collect img src attributes in an array var innerHeight = window.innerHeight; // get view port dimensions if(imgs) { for(i=0; i < imgs.length; i++) { var pos = imgs[i].getBoundingClientRect(); /* if image is visible already then exclude from images to load later */ /* if its not loaded then save its position [i] in the imgs array, its vertical position, its load status and src attribute*/ pos.top < innerHeight ? imgs[i].src = imgs[i].getAttribute("data-lsrc") : imgsData.push({ i: i, y:pos.top, loaded: false, dsrc: imgs[i].getAttribute("data-lsrc")}); } } /* Call check elements on scroll - this will get the current top position and will set the src of the image to its proper value if it should be now in view */ function checkElements(elems) { var offset = soffset || 0; /*elems refers to imgsData */ for(j=0; j<elems.length; j++) { if(!elems[j].loaded && (elems[j].y < innerHeight+document.body.scrollTop+offset)) { imgs[elems[j].i].src = elems[j].dsrc; elems[j].loaded = true; console.log('Img '+ elems[j].i + ' loaded.'); } } } document.onscroll = function(){ checkElements(imgsData); }; /* run the function once to load images that are initally in view - prior to any scrolling */ checkElements(imgsData); /* when you call ll it will return the number of images that were processed by LLL */ return {count: imgsData.length}; };
The usage of the script is below:
Call the ll
function with window
, document
as is first two parameters and offset
as its third parameter. I use offset to tell the image loader to load images early (before the image reaches the view port). The reason is simply so that the user doesn’t have to see that the images are loading just now. Some people (like Politico) use a jQuery ‘fade in’ to give the user a better impression.
The last parameter is the collection of images in the DOM with the data-lsrc attribute. When you call ll it will look something like this:
var imgs = $("img[data-lsrc]"); lz = ll(document, window, 1000, imgs);
In my next post I will show you how I populated the data-lsrc attribute in WordPress+PHP and how I added the images to the colorbox to give them a nice lightbox effect when the user clicks on an image.
Recent Comments