I am using IntersectionObserver.js with data-srcset to create a lazy load but images aren't displaying correctly as per the resolution, every time the browser chooses the largest image... in this case it is the image with 450 width, ignoring the others width's (100px, 200px, 300px, 400px).
Here is the JS code doing used to lazy-load:
const images = document.querySelectorAll('img[data-src]');
const config = {
rootMargin: '50px 0px',
threshold: 0.01
};
let observer;
if ('IntersectionObserver' in window) {
observer = new IntersectionObserver(onChange, config);
images.forEach(img => observer.observe(img));
} else {
console.log('%cIntersection Observers not supported', 'color: red');
images.forEach(image => loadImage(image));
}
const loadImage = image => {
image.classList.add('fade-in');
image.src = image.dataset.src;
image.srcset = image.dataset.srcset;
}
function onChange(changes, observer) {
changes.forEach(change => {
if (change.intersectionRatio > 0) {
// Stop watching and load the image
loadImage(change.target);
observer.unobserve(change.target);
}
});
}
And here is the HTML code used (it's an article category page):
<img class="img-fluid"
src="data:image/webp;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
data-src="https://ik.imagekit.io/amalgama/usuarios/administradores/admin/artigos/thumb/7-passos-para-sair-das-dividas-e-se-tornar-um-empreendedor.webp?tr=w-100"
alt="bla bla bla"
title="bla bla bla"
data-srcset="https://ik.imagekit.io/amalgama/usuarios/administradores/admin/artigos/thumb/7-passos-para-sair-das-dividas-e-se-tornar-um-empreendedor.webp?tr=w-100 100w,
https://ik.imagekit.io/amalgama/usuarios/administradores/admin/artigos/thumb/7-passos-para-sair-das-dividas-e-se-tornar-um-empreendedor.webp?tr=w-200 200w,
https://ik.imagekit.io/amalgama/usuarios/administradores/admin/artigos/thumb/7-passos-para-sair-das-dividas-e-se-tornar-um-empreendedor.webp?tr=w-300 300w,
https://ik.imagekit.io/amalgama/usuarios/administradores/admin/artigos/thumb/7-passos-para-sair-das-dividas-e-se-tornar-um-empreendedor.webp?tr=w-400 400w,
https://ik.imagekit.io/amalgama/usuarios/administradores/admin/artigos/thumb/7-passos-para-sair-das-dividas-e-se-tornar-um-empreendedor.webp?tr=w-450 450w"
width="450px"
height="278px">
You can see the demo page running at URL below:
Well, do you know why the other sizes aren't displaying? Only the largest image in every screen ;(
I forgot to post the solution before, but here we go, after many tests I finally found a way to work with data-srcset, lazyload, imagekit and declaring height and width to optimize google page insight. It works with desktop and mobile, with all types of device pixels ratios... Hope it helps someone :)
The media size needs to be the double (don't ask me why lol)
Demo production link.
CODE
<script src="https://cdn.jsdelivr.net/npm/intersection-observer@0.12.2/intersection-observer.min.js"></script>
Javascript:
const config = {
rootMargin: '50px 0px',
threshold: 0.01
};
if ('IntersectionObserver' in window) {
LazyLoad();
} else {
ShowAllImages();
}
function LazyLoad(){
let observer;
let images = document.querySelectorAll('img[data-src]');
observer = new IntersectionObserver(onChange, config);
images.forEach(img => observer.observe(img));
}
function ShowAllImages() {
images.forEach(image => loadImage(image));
}
const loadImage = image => {
image.classList.add('fade-in');
image.src = image.dataset.src;
image.srcset = image.dataset.srcset;
}
function onChange(changes, observer) {
changes.forEach(change => {
if (change.intersectionRatio > 0) {
// Stop watching and load the image
loadImage(change.target);
observer.unobserve(change.target);
}
});
}
HTML:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<figure>
<img
width="950" height="950"
src="data:image/webp;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
data-src="http://placehold.it/950x950"
sizes="(max-width: 125px),
(max-width: 150px),
(max-width: 175px),
(max-width: 200px),
(max-width: 225px),
(max-width: 250px),
(max-width: 275px),
(max-width: 300px),
(max-width: 325px),
(max-width: 350px),
(max-width: 375px),
(max-width: 400px),
(max-width: 425px),
(max-width: 450px),
(max-width: 475px),
(-webkit-min-device-pixel-ratio: 1.1) AND (-webkit-max-device-pixel-ratio: 1.5) 80.5vw,
(-webkit-min-device-pixel-ratio: 1.6) AND (-webkit-max-device-pixel-ratio: 2) 57.5vw,
(-webkit-min-device-pixel-ratio: 2.1) AND (-webkit-max-device-pixel-ratio: 2.5) 42.5vw,
(-webkit-min-device-pixel-ratio: 2.6) AND (-webkit-max-device-pixel-ratio: 3) 39.5vw,
(-webkit-min-device-pixel-ratio: 3.1) AND (-webkit-max-device-pixel-ratio: 3.5) 32.5vw,
(-webkit-min-device-pixel-ratio: 3.6) AND (-webkit-max-device-pixel-ratio: 4) 28.5vw"
data-srcset="http://placehold.it/250x250 250w,
http://placehold.it/300x300 300w,
http://placehold.it/350x350 350w,
http://placehold.it/400x400 400w,
http://placehold.it/450x450 450w,
http://placehold.it/500x500 500w,
http://placehold.it/550x550 550w,
http://placehold.it/600x600 600w,
http://placehold.it/650x650 650w,
http://placehold.it/700x700 700w,
http://placehold.it/750x750 750w,
http://placehold.it/800x800 800w,
http://placehold.it/850x850 850w,
http://placehold.it/900x900 900w,
http://placehold.it/950x950 950w"
>
</figure>