Back to the lesson

Load visible images

importance: 4

Let’s say we have a slow-speed client and want to save his 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.

Open a sandbox for the task.

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).

Open the solution in a sandbox.