¿Qué es el IntersectionObserver y cómo puede mejorar el rendimiento de tu proyecto?
El IntersectionObserver es una poderosa Web API que permite detectar cuando un elemento del DOM es visible dentro del "viewport" de tu navegador. Este proceso es crítico para optimizar el rendimiento de las aplicaciones, dado que evita el desperdicio de recursos cargando elementos que no son visibles para el usuario. Esta técnica no solo es simple, sino también poderosa, y ha evolucionado considerablemente gracias a la continua mejora de los observables.
¿Cómo implementar un IntersectionObserver en tu proyecto?
Para implementar un IntersectionObserver en tu proyecto y optimizar el manejo de imágenes o elementos en React, necesitas seguir algunos pasos clave:
Crear el Observador: Define un nuevo observador con la API Web disponible en el objeto window, el cual requiere un callback.
¿Cómo manejar el estado de las imágenes para cargarlas dinámicamente?
La carga dinámica de imágenes mejora la experiencia del usuario al representar solo aquellas que son necesarias. Para eso, puedes utilizar useState en React para cambiar el estado de las imágenes:
Estado inicial: Define un estado que mantenga el valor de la imagen.
const[source, setSource]=useState('');
Actualizar la fuente al intersectar: Cambia el estado de la URL de la imagen cuando el observador detecta visibilidad.
if(entry.isIntersecting){setSource(imageURL);}
Renderizar espacio de carga: Usa una imagen en blanco pintada con CSS para proporcionar una mejor experiencia.
const placeholder ='data:image/gif;base64,...';// Imagen transparente en base64
¿Cómo mejorar la experiencia de usuario con detalles estéticos?
La sensación de que "algo está sucediendo" es esencial para la percepción del rendimiento. Utilizar trucos como renderizar imágenes transparentes con color de fondo ayuda significativamente:
Imagen en base64: Esta técnica evita peticiones adicionales al servidor y se carga inmediatamente.
Colorear con CSS: Mejorar el placeholder visualmente con Tailwind o cualquier otro framework CSS puede ser crucial.
Por ejemplo, usando Tailwind puedes definir el color de fondo así:
¿Por qué usar TypeScript en combinación con IntersectionObserver?
TypeScript proporciona una asistencia invaluable mediante su autocompletado y chequeo de tipos. Te permite trabajar de manera más eficiente y con menos errores:
Ayudas de código: Con TypeScript, obtiene sugerencias automáticas que evitan el error humano.
Manejo de errores: Aunque puede advertirte de potenciales errores, también puedes omitir ciertas validaciones intencionalmente si estás seguro de tu lógica.
En suma, el uso efectivo del IntersectionObserver, React y TypeScript puede elevar el rendimiento y usabilidad de tu aplicación web, creando una experiencia más fluida y optimizada para los usuarios. Con estos fundamentos, estás en camino de dominar técnicas avanzadas que se traducen en software robusto y eficiente. No dudes en seguir explorando y mejorando tus habilidades para llevar tus proyectos al siguiente nivel.
Hola a todos devs!!. Les dejare un consejo de un problema que me paso a mi. Cuando cargaba varias imagenes con el boton y luego daba scroll hacia abajo veia que en mi Network se cargaban todas al mismo tiemo antes de hacer más scroll.
.
Me di cuenta de que era por que al no estar renderizadas las imagenes quedan todas juntas y al hacer scroll es como si todas aparecieran en la pantalla.
.
Lo arregle metiendo la imagen dentro de un div con margin y de esta manera ya existe una separacion entre las imagenes que no estan renderizadas aun.
muy buen consejo gracias
Sería buena idea ser explicitos también con el useState para que quede de la siguiente manera?
hoy en día también existe el atributo loading="lazy" que se puede colocar dentro de image y esta funcionalidad nativa de los navegadores permite que las imágenes e iframes se carguen solo cuando están cerca de entrar en la ventana visible (viewport)
🔹 Lazy Loading de Imágenes con IntersectionObserver
El objetivo de este patrón es cargar las imágenes solo cuando entran en el viewport, lo que mejora el rendimiento y reduce el consumo de datos. 💨📷
import{ useRef, useEffect, useState }from"react";type Props={image: string;// URL real de la imagen};exportconstRandomFox=({ image }:Props):JSX.Element=>{// 🔹 Referencia al elemento <img>const node = useRef<HTMLImageElement>(null);// 🔹 Estado del src de la imagen// Inicialmente usamos un placeholder en base64 (SVG vacío)const[src, setSrc]=useState("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIwIiBoZWlnaHQ9IjMyMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiLz4=");useEffect(()=>{// 🔹 Creamos un IntersectionObserverconst observer =newIntersectionObserver((entries)=>{ entries.forEach((entry)=>{// 🔹 Cuando la imagen entra en el viewportif(entry.isIntersecting){setSrc(image);// 📥 Cargamos la imagen real}});});// 🔹 Observamos el nodo si existeif(node.current){ observer.observe(node.current);}// 🔹 Limpiamos el observer al desmontar el componentereturn()=>{ observer.disconnect();};},[image]);return(<img
ref={node}// 🔹 Referencia para el observer width={320} height="auto" src={src}// 🔹 Imagen placeholder o real className="rounded"/>);};
🔹 Explicación paso a paso
Referencia del nodo 🖇️
useRef<HTMLImageElement>(null) nos permite acceder al <img> en el DOM y observar cuándo aparece en pantalla.
Placeholder inicial 🟦
Se usa un SVG muy ligero como imagen inicial (src), evitando que el <img> aparezca vacío y mejorando la experiencia de usuario.
Intersection Observer 👀
Detecta cuando el <img> entra en el viewport.
entry.isIntersecting es true cuando la imagen es visible.
Entonces actualizamos src al valor real (setSrc(image)), cargando la imagen solo cuando se necesita.
Cleanup 🧹
Siempre desconectamos el observer con observer.disconnect() al desmontar el componente para evitar fugas de memoria.
Ventajas 🌟
🚀 Mejora el rendimiento de la página.
📉 Reduce el uso de ancho de banda.
🖼️ Mejora la experiencia del usuario con imágenes que se cargan de forma progresiva.
🔹 Tip extra
Si quieres que la imagen solo se cargue una vez, puedes usar { once: true } en las opciones del observer:
usa en las dependencies del useEffect [setSrc, image]
¿Por qué el profesor usó una imagen en base64 mientras que carga la imagen de la URL? ¿Alguien me explica? A mí me funciona igual solo especificando un width, height y background-color al elemento hasta que eventualmente cargue la imagen.
Creo que son dos formas diferentes igualmente validas de implementar la misma funcionalidad
excelente el truco de la img en base 64 ! lo voy a usar en todos mis proyectos !
Si quieren que la imagen solo sea visible si esta aparece completamente en el viewport, pueden agregar la opcion treshhold: useEffect(() ``=>`` { ``let`` options = { threshold: 1.0 }; ``let`` observer = new IntersectionObserver((``entries``) ``=>`` { entries.forEach((``entry``) ``=>`` entry.isIntersecting && setSrc(image)); }, options); if (node.current) { observer.observe(node.current); } return () ``=>`` observer.disconnect(); }, [image]);