You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

1 Días
10 Hrs
59 Min
57 Seg

Lazy Loading

7/20
Resources

How to implement lazy loading on images with Intersection Observer?

Implementing lazy loading is an efficient technique that improves the performance of web applications by loading images only when users see them. Using Intersection Observer for this task becomes an optimal solution because of its ability to handle multiple inputs efficiently and easily.

How to configure the Intersection Observer?

To implement lazy loading in a project, it is essential to configure the Intersection Observer correctly. A crucial step is to create the observer before handling specific elements, such as images.

const lazyLoader = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const image = entry.target; image.src = image.dataset.src; observer.unobserve(image); } } );});
  • Callback Function: Used to handle the actions each time an element enters or leaves the view.
  • Entries: Represents the individual elements that the observer is following.
  • Observer: Yes, this object allows to stop observing an image once it has been loaded.

How to structure your code for lazy loading?

Organizing your code well is key to maintaining clarity and efficiency. Adopting a modular structure can make it easier to manipulate the DOM for lazy loading.

function createMovies(movies, container, lazyLoad = false) { movies.forEach(movie => { const movieImage = document.createElement('img');
 if (lazyLoad) { movieImage.dataset.src = movie.imageURL; lazyLoader.observe(movieImage); } else { movieImage.src = movie.imageURL; }
 container.appendChild(movieImage); }); });}
  • CreateMovies function: Generates and manages each of the movie images to be watched and loaded as needed.
  • LazyLoad option: Allows you to define if you want to apply the lazy loading to the images of a specific container.

How to add the observer to the images?

Implementing the observer in a container is necessary so that the images are observed and loaded when entering the viewport.

function observeImages(images) { images.forEach(image => lazyLoader.observe(image));}
  • Observe method: This method gives the observer the ability to follow one or more elements (in this case, images).

What additional techniques can be implemented?

To improve and make the implementation even more robust, you can employ some additional techniques:

  • Load a default image: If some image cannot be loaded, use a default image that offers the same visual experience to the user.
image.onerror = () => image.src = 'default-image-url.jpg';
  • Check the isIntersecting property: Only load the image when it is actually visible to the user.

What to avoid when implementing lazy loading?

When implementing this functionality, it is advisable to maintain a balance between loading optimization and user experience:

  • Avoid loading all images at once: This implementation makes sure that only visible images are loaded.
  • Monitor CSS: Take care that images are sized properly initially, to avoid them all displaying incorrectly.

Implementing lazy loading correctly with Intersection Observer can save you resources, improve the user experience and, above all, ensure that your application runs more efficiently. If a technique doesn't fit your needs, customize it and share it with the community for further learning.

Contributions 12

Questions 4

Sort by:

Want to see more contributions, questions and answers from the community?

También si quieren evitar el problema que dice @JuanDC, en el que las imágenes cargan pequeñas, la manera de solucionarlo es eliminando el CLS (Culmulative Layout Shift - Cambio de diseño acumulativo), que básicamente es cuando un elemento mueve el diseño después de cargar el html base, y resulta molesto para los usuarios.

Para esto existen varias técnicas, la mejor para mí es: Teniendo en cuenta el aspect ratio de la imagen, agregar un width y height fijo y proporcional al aspect ratio, para que con unas propiedades, css pueda calcular su tamaño, y siempre mantenga la proporción, también sirve para agregar un skeleton loader responsive a las imágenes.
¿Qué es el aspect ratio?

¿Pero esto qué significa, y cómo se hace?
Por ejemplo, en las imágenes de nuestro proyecto, ya sea que pidamos una imagen de 200x300, 300x450 … Etc. Estas imágenes (de los cards) siempre tendrán un aspec ratio de 2:3, ahora utilizaremos esto en código:

<img className="img-responsive" alt="imagen" width="200" height="300" />						

Para que CSS pueda calcular la altura, necesita las propiedades: aspect-ratio: n/n;, height: auto; y el width que necesitemos, en este caso puede ser 100%, porque en el código utilizo un grid

.img-responsive {
	aspect-ratio: 2 / 3; // O también 200 / 300
	border-radius: 1rem;
	height: auto;
	object-fit: cover;
	vertical-align: top;
	width: 100%;
}

También aquí hay información sobre el CLS, esta y otras técnicas para solucionarlo, en el que seguro lo explican más detallado, y mejor. 😅

Con esto, evitamos que cuando carguen las imágenes, muevan todo lo que está debajo de ellas, porque ya tienen su espacio asignado. 😃

Algo similar con el atributto loading, sin el intersectionObserver

movieImg.setAttribute('loading', 'lazy') 

Si las imagenes ya estan cargadas ya no es necesario el observer so…

if (entry.isIntersecting) {
	entry.target.setAttribute('src', url)
	lazyLoader.unobserve(entry.target)
}

antes del lazuLoading al verificar el performance de la aplicación con lighthouse mi rendimiento en mobile era del 3, después de implementarlo subió al51

Al final el profe dice:
si el height de las imágenes está en 0 no va a tomar el lazy
.
Esto es lo que pasa con las imágenes en la sección categoría. Por eso cargan todas al mismo tiempo.
.
Mi solución fue agregar esto al css

.genericList-container .movie-container .movie-img {
    height: 270px;
    min-height: 270px;
    max-height: 270px;
    width: 170px;
    min-width: 170px;
    max-width: 170px;
}

Me encanta la actitud de Juan los cursos aparte de interesantes y importantes, son divertidos n.n

Lazy Loading (carga diferida en español) es una técnica de optimización utilizada en el desarrollo de aplicaciones web y móviles para retrasar la carga de recursos o elementos hasta que sean realmente necesarios. Esta técnica mejora el rendimiento y la experiencia del usuario al reducir el tiempo de carga inicial de la página o aplicación y el uso de ancho de banda. 🧑‍💻🧑‍💻

mi aporte es no usar la función setAttribute o getAttribute, ya el objeto target, tiene el path

const lazyLoader=new IntersectionObserver(entries=>{
    entries.forEach(entry=>{
        if (entry.isIntersecting) {
            entry.target.src=entry.target.dataset.src;
        }
    });
});

Le agregué que deje de escuchar el nodo (imagen) cuando ya la cargó.
Es decir, que no la vuelva a cargar.

const lazyLoader = new IntersectionObserver((entries)=>{
    entries.forEach((image)=>{
        if (image.isIntersecting ) {
            const url = image.target.getAttribute('data-img');
            image.target.setAttribute('src', url);
            lazyLoader.unobserve(image.target);
        }
    });
});

Seguí los pasos de esta clase

agregue una validacion hay un pequeño problema y es que igual se hace una petición aun cuando se carga la imagen ```js const lazyLoader = new IntersectionObserver((entries) => { entries.forEach((entry) => { const element = entry.target; if (entry.isIntersecting && element.dataset['src'] && !element.src) { const url = element.dataset['src']; element.src = url; } }); }); ```

Aquí una respusta a cual es mejor: lazo loading o intersectionObserver.

https://stackoverflow.com/questions/72847077/img-loading-lazy-vs-intersection-observer

RPTA: intersection observer da más control…pero ambas opciones hacen lo mismo.

Y si no lo resolvimos de ninguna manera? :’(

Llevo un tiempo ya haciendo los cursos de programación y la verdad, no se me habría ocurrido hacer todo esto.

F para mí 😅