I recently presented a workshop at Fluent conference and in preparing for the session I was looking for examples of lazy loading responsive images, mainly an image that was displayed using the <picture> element. If you are anything like me when programming and write one line of code followed by a line sourced from Stack Overflow then you will be as surprised (and disappointed) as me not to find anything.
I did find many articles advising just to use the library lazysizes or similar libraries, but there is always something that doesn’t sit right with me about blindly adding libraries to your website.
So with no help from Stack Overflow (and other Google searches) and a desire NOT to use a library below is a simple enough solution I came up with.
Let’s assume you want to create a simple <picture> that swaps out 2 different size images (400 & 800) based on screen size and also swaps the format to webP when supported in the browser. The images are already created with the same filenames, but exist in a folder structure for sizes.
<picture id="lazyPicture"> <source type="image/webp" srcset="/400/hero.webp 400w, /800/hero.webp 800w" sizes="100vw" /> <img src="/800/hero.jpg" srcset="/400/hero.jpg 400w, /800/hero.jpg 800w" sizes="100vw" /> </picture >
In order for the browser not to load this image on first pageload we need to strip it down and remove any src or srcset attributes. In addition to these we also need to add a data-src attribute to hold the filename. Note this does NOT include the file extension.
<picture id="lazyPicture" data-src="hero"> </picture >
Once the markup has been changed we need to build the function to get the data-src value and swap this into the <source> element and the <img> element.
var x = document.getElementByID("lazyPictures"); var fileName = x.getAttribute("data-src"); /* create & append the source element */ var src = document.createElement("source"); src.type = "image/webp"; src.srcset = "/400/"+fileName+".webp 400w, /800/"+fileName+".webp 800w"; src.sizes = "100vw"; x.appendChild(src); /* create & append img element */ var img = document.createElement("img"); img.src = "/800/"+filename+".jpg"; img.srcset = "/400/"+fileName+".jpg 400w, /800/"+fileName+".jpg 800w"; img.sizes = "100vw"; x.appendChild(img);
The code above finds our <picture> by using the id attribute. Then it finds the filename for the image held in the data-src attribute. Once it has this we can create additional elements for <source> and <img> and finally append these to our <picture>. We now have a fully functioning responsive image that can be lazy loaded.