Load visible images
Let’s say we have a slow-speed client and want to save their mobile traffic.
For that purpose we decide not to show images immediately, but rather replace them with placeholders, like this:
<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">
So, initially all images are placeholder.svg
. When the page scrolls to the position where the user can see the image – we change src
to the one in data-src
, and so the image loads.
Here’s an example in iframe
:
Scroll it to see images load “on-demand”.
Requirements:
- When the page loads, those images that are on-screen should load immediately, prior to any scrolling.
- Some images may be regular, without
data-src
. The code should not touch them. - Once an image is loaded, it should not reload any more when scrolled in/out.
P.S. If you can, make a more advanced solution that would “preload” images that are one page below/after the current position.
P.P.S. Only vertical scroll is to be handled, no horizontal scrolling.
The onscroll
handler should check which images are visible and show them.
We also may want to run it when the page loads, to detect immediately visible images prior to any scrolling and load them.
If we put it at the <body>
bottom, then it runs when the page content is loaded.
// ...the page content is above...
function isVisible(elem) {
let coords = elem.getBoundingClientRect();
let windowHeight = document.documentElement.clientHeight;
// top elem edge is visible OR bottom elem edge is visible
let topVisible = coords.top > 0 && coords.top < windowHeight;
let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
return topVisible || bottomVisible;
}
showVisible();
window.onscroll = showVisible;
For visible images we can take img.dataset.src
and assign it to img.src
(if not did it yet).
P.S. The solution also has a variant of isVisible
that “pre-loads” images that are within 1 page above/below (the page height is document.documentElement.clientHeight
).