Cargar imágenes visibles
Digamos que tenemos un cliente con baja velocidad de conexión y queremos cuidar su tarifa de datos.
Para ello decidimos no mostrar las imágenes inmediatamente, sino sustituirlas por marcadores de posición, como este:
<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">
Así que, inicialmente todas las imágenes son placeholder.svg
. Cuando la página se desplaza a la posición donde el usuario puede ver la imagen – cambiamos src
a data-src
, y así la imagen se carga.
Aquí hay un ejemplo en iframe
:
Desplázate para ver las imágenes cargadas “bajo demanda”.
Requerimientos:
- Cuando la página se carga, las imágenes que están en pantalla deben cargarse inmediatamente, antes de cualquier desplazamiento.
- Algunas imágenes pueden ser regulares, sin
data-src
. El código no debe tocarlas. - Una vez que una imagen se carga, no debe recargarse más cuando haya desplazamiento arriba/abajo.
P.D. Si puedes, haz una solución más avanzada para “precargar” las imágenes que están más abajo/después de la posición actual.
Post P.D. Sólo se debe manejar el desplazamiento vertical, no el horizontal.
El manejador onscroll
debería comprobar qué imágenes son visibles y mostrarlas.
También queremos que se ejecute cuando se cargue la página, para detectar las imágenes visibles inmediatamente y cargarlas.
El código debería ejecutarse cuando se cargue el documento, para que tenga acceso a su contenido.
O ponerlo en la parte inferior del <body>
:
// ...el contenido de la página está arriba...
function isVisible(elem) {
let coords = elem.getBoundingClientRect();
let windowHeight = document.documentElement.clientHeight;
// ¿El borde superior del elemento es visible?
let topVisible = coords.top > 0 && coords.top < windowHeight;
// ¿El borde inferior del elemento es visible?
let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
return topVisible || bottomVisible;
}
La función showVisible()
utiliza el control de visibilidad, implementado por isVisible()
, para cargar imágenes visibles:
function showVisible() {
for (let img of document.querySelectorAll('img')) {
let realSrc = img.dataset.src;
if (!realSrc) continue;
if (isVisible(img)) {
img.src = realSrc;
img.dataset.src = '';
}
}
}
showVisible();
window.onscroll = showVisible;
P.D. La solución tiene una variante de isVisible
que “precarga” imágenes que están dentro de 1 página por encima/debajo del desplazamiento del documento actual.