react-lazy-img-observer
v1.5.1
Published
A React component for lazy loading images with Intersection Observer
Maintainers
Readme
📷 ImageLazy (v1.5.0)
ImageLazy is a lightweight and customizable React component for lazy loading images using the Intersection Observer API. It includes fallback handling, visual effects, and support for custom loaders and transitions — perfect for performance-oriented applications.
ImageLazy es un componente liviano y personalizable de React para cargar imágenes perezosamente (lazy load) usando la API de Intersection Observer. Incluye manejo de errores, efectos visuales, y soporte para spinners personalizados y transiciones — ideal para aplicaciones optimizadas.
📚 Contenido
- 📦 Instalación
- ✨ Características Nuevas
- 🚀 Uso Básico
- 📃 Tabla de Props
- 🎨 Ejemplos Avanzados
- 💡 Uso de Props
- 🔁 Efectos Visuales
- 🔧 Cómo funciona
- ❓ FAQ
- 📊 Comparación
- 📄 Licencia
- 👤 Autor
📦 Installation / Instalación
npm install react-lazy-img-observer✨ New Features / Características Nuevas
- Next.js 13+ Ready: Full support for App Router with
"use client"directive. - SSR Optimized: Zero hydration mismatches or server warnings.
- TypeScript Native: Written in TS for perfect autocompletion.
- Performance: Improved threshold defaults and memoized styles.
📃 Props Table / Tabla de Props
| Prop | Tipo | Por Defecto | Descripción (ES) / Description (EN) |
| -------------------- | ----------------------------------------- | ----------- | --------------------------------------------------------------- |
| src | string | – | URL de la imagen / Image URL |
| alt | string | – | Texto alternativo / Alt text |
| srcSet | string | – | Set de imágenes responsive / Responsive image set |
| sizes | string | – | Tamaños para srcSet / Responsive sizes |
| width | number | – | Ancho fijo / Fixed width |
| height | number | – | Alto fijo / Fixed height |
| id | string \| number | – | ID del elemento / Element ID |
| className | string | – | Clase CSS personalizada / Custom CSS class |
| title | string | – | Atributo title del tag img / Tooltip text |
| useTitleFromAlt | boolean | false | Usa el alt como title / Use alt value as title |
| extraData | ImgHTMLAttributes<HTMLImageElement> | – | Props adicionales para img / Extra native props |
| viewTransitionName | string | – | Nombre para View Transitions API |
| style | CSSProperties | – | Estilos inline / Inline styles |
| backgroundColor | string | – | Color de fondo mientras carga / Background while loading |
| animationDuration | string | 0.9s | Duración de la transición / Animation duration |
| blurAmount | string | 20px | Desenfoque inicial / Initial blur effect |
| fallbackSrc | string | – | Imagen fallback si falla / Fallback image if loading fails |
| threshold | number | 0.5 | Umbral de visibilidad / Intersection threshold |
| transitionType | 'blur' \| 'fade' \| 'scale' \| 'custom' | 'blur' | Tipo de transición visual / Type of transition |
| onLoadComplete | () => void | – | Callback al cargar / Callback after image is fully loaded |
| visibleByDefault | boolean | false | Cargar sin lazy / Load immediately without waiting for viewport |
| loadingComponent | ReactNode | – | Componente mientras carga / Custom loader component |
🔁 Effects / Efectos Visuales
| Effect | Description |
| -------- | ----------------------------------------------------------------------------------------- |
| blur | Apply blur and remove it after load / Aplicar desenfoque y eliminarlo después de cargar |
| fade | Fade in the image / Desvanecimiento de la imagen |
| scale | Slight zoom effect / Ligero efecto de zoom |
| custom | Use your own CSS (add class to image) / Utilice su propio CSS (agregue clase a la imagen) |
🚀 Usage / Uso Básico
import ImageLazy from "react-lazy-img-observer";
function App() {
return (
<ImageLazy
src="https://example.com/photo.jpg"
alt="Example image"
width={400}
height={300}
/>
);
}✅ Explicación:
src: URL de la imagen / Image URL.alt: Texto descriptivo para accesibilidad y SEO / Descriptive text for accessibility and SEO.width/height: Definen tamaño fijo (opcional pero recomendable para evitar reflow / Define fixed size (optional but recommended to avoid reflow).
🎨 Advanced Example with Spinner and Fallback / Ejemplo Avanzado con Spinner y Fallback
import ImageLazy from "react-lazy-img-observer";
const Spinner = () => <div className="spinner">Loading...</div>;
function GalleryImage() {
return (
<ImageLazy
src="/img/cat.webp"
alt="Cute Cat"
width={300}
height={200}
fallbackSrc="/img/fallback.webp"
backgroundColor="#eee"
animationDuration="1s"
blurAmount="8px"
transitionType="fade"
loadingComponent={<Spinner />}
/>
);
}💡 Prop Usage with Examples / Uso de Props con Ejemplos
📍 fallbackSrc
<ImageLazy
src="/img/main.jpg"
fallbackSrc="/img/fallback.jpg"
alt="Imagen principal"
/>👉 Si la imagen original falla, se muestra automáticamente la alternativa / If the original image fails, the alternative is automatically displayed.
🎨 backgroundColor
<ImageLazy
src="/img/pic.jpg"
alt="Imagen con fondo gris"
backgroundColor="#f0f0f0"
/>👉 Color visible mientras la imagen carga (mejora UX) / Color visible while image loads (UX improvement).
💫 blurAmount y animationDuration
<ImageLazy
src="/img/blurred.jpg"
alt="Efecto blur personalizado"
blurAmount="5px"
animationDuration="2s"
/>👉 Controla el desenfoque inicial y duración del efecto / Controls the initial blur and duration of the effect.
🌀 transitionType
<ImageLazy src="/img/pic.jpg" alt="Fade in" transitionType="fade" />
<ImageLazy src="/img/pic.jpg" alt="Scale in" transitionType="scale" />
<ImageLazy src="/img/pic.jpg" alt="Custom CSS" transitionType="custom" className="img-fx" />CSS (ejemplo avanzado):
.img-fx {
opacity: 0;
transform: scale(0.8) rotate(-2deg);
transition: all 0.8s ease;
}
.img-fx.loaded {
opacity: 1;
transform: scale(1) rotate(0deg);
}👉 Usa custom para controlar completamente la animación con tu propio CSS / Use custom to fully control the animation with your own CSS.
🔁 visibleByDefault
<ImageLazy src="/img/pic.jpg" alt="Carga inmediata" visibleByDefault={true} />👉 Útil cuando no deseas esperar a que la imagen entre al viewport (ej: SSR o cuando ya está precargada / Useful when you don't want to wait for the image to enter the viewport (e.g. SSR or when it is already pre-loaded).
🔧 How it works / ¿Cómo funciona?
- When
visibleByDefaultisfalse(default), the image loads only when it's in the viewport (IntersectionObserver)/CuandovisibleByDefaultesfalse(predeterminado), la imagen se carga solo cuando está en la ventana gráfica (IntersectionObserver). - If
visibleByDefaultistrue, the image is loaded immediately (useful for SSR or cached images)/SivisibleByDefaultestrue, la imagen se carga inmediatamente (útil para SSR o imágenes almacenadas en caché). - You can add a custom CSS transition, fallback, background color, and even a loading spinner/Puede agregar una transición CSS personalizada, una alternativa, un color de fondo e incluso un indicador de carga.
🧭 loadingComponent
<ImageLazy
src="/img/loading.jpg"
alt="Con spinner"
loadingComponent={<div className="spinner">Cargando...</div>}
/>👉 Muestra un componente personalizado mientras se carga la imagen / Display a custom component while the image is loading.
🧪 onLoadComplete
function handleLoad() {
console.log("¡Imagen completamente cargada!");
}
<ImageLazy
src="/img/event.jpg"
alt="Imagen con evento"
onLoadComplete={handleLoad}
/>;🔁 onLoadComplete con lógica avanzada / with advanced logic
const [estado, setEstado] = useState("cargando");
<ImageLazy
src="/img/camara.jpg"
alt="Avanzado"
onLoadComplete={() => setEstado("cargada")}
/>
<p>Estado de imagen: {estado}</p>✅ onLoadComplete con múltiples imágenes / with multiple images
const [cargas, setCargas] = useState(0);
const incrementar = () => setCargas((prev) => prev + 1);
<ImageLazy src="/img/uno.jpg" alt="uno" onLoadComplete={incrementar} />
<ImageLazy src="/img/dos.jpg" alt="dos" onLoadComplete={incrementar} />
<p>Imágenes cargadas: {cargas}</p>🧷 useTitleFromAlt
<ImageLazy
src="/img/title.jpg"
alt="Una imagen informativa"
useTitleFromAlt={true}
/>👉 Usa el valor de alt también como atributo title automáticamente. Útil para tooltips nativos / Automatically uses the alt value as the title attribute as well. Useful for native tooltips..
🖼 viewTransitionName
<ImageLazy
src="/img/view.jpg"
alt="Transición de vista"
viewTransitionName="fade-image"
/>👉 Para integrar con la API de view-transition (Chrome ≥ 111) y hacer animaciones entre páginas con <ViewTransition> / To integrate with the view-transition API (Chrome ≥ 111) and make animations between pages with <ViewTransition>.
🏷️ id (uso en scroll o testing)
<ImageLazy
src="/img/anchor.jpg"
alt="Imagen anclada"
id="fotoPrincipal"
/>
<a href="#fotoPrincipal">Ir a la imagen</a>👉 Permite identificar la imagen fácilmente para navegación, testing u operaciones DOM / Allows you to easily identify the image for navigation, testing, or DOM operations..
📐 srcSet y sizes
<ImageLazy
src="/img/400.jpg"
srcSet="/img/400.jpg 400w, /img/800.jpg 800w"
sizes="(max-width: 600px) 400px, 800px"
alt="Imagen responsive"
/>👉 Mejora el rendimiento en dispositivos móviles cargando imágenes más ligeras según el ancho de pantalla / Improves performance on mobile devices by loading images smaller based on screen width.
🧩 extraData, className, style
<ImageLazy
src="/img/extra.jpg"
alt="Con extras"
className="rounded shadow"
style={{ objectFit: "cover" }}
extraData={{ draggable: false, crossOrigin: "anonymous" }}
/>👉 Puedes personalizar todo el comportamiento nativo de <img> sin limitaciones / You can customize all native behavior of <img> without limitations.
🌐 SSR Compatible / Compatible con SSR
ImageLazy is safe to use in SSR environments (like Next.js). It checks for window and disables IntersectionObserver logic when rendering on the server.
ImageLazy es seguro para entornos con renderizado del lado del servidor como Next.js. Detecta si window está disponible antes de usar IntersectionObserver.
📊 Comparison with react-lazy-load-image-component / Comparación con react-lazy-load-image-component
| Feature / Característica | ImageLazy ✅ | react-lazy-load-image-component ❌ |
| ------------------------------------------- | ---------------------------------- | ---------------------------------------------- |
| Lightweight & no external dependencies | ✅ Yes / Sí | ❌ No (más pesado y con múltiples componentes) |
| SSR Friendly (Next.js compatible) | ✅ Yes / Sí | ✅ Yes / Sí |
| Custom transitions via CSS (custom) | ✅ Yes / Sí | ❌ No |
| Native spinner support (loadingComponent) | ✅ Yes / Sí | ❌ No (solo con workarounds) |
| Fallback support (fallbackSrc) | ✅ Yes / Sí | ✅ Yes / Sí |
| Responsive images (srcSet and sizes) | ✅ Yes / Sí | ✅ Yes / Sí |
| Load other elements lazily | ❌ Images only / Solo imágenes | ✅ Yes (via LazyLoadComponent) |
| Built-in effects | ✅ blur, fade, scale, custom | ✅ blur, opacity, bw |
| Transition customization | ✅ Total freedom with CSS | ❌ Limited |
❓ FAQ
¿Por qué mi imagen no se muestra? / Why isn't my image showing?
Asegúrate de que src no sea null, y revisa si visibleByDefault está en true / Make sure src is not null, and check if visibleByDefault is set to true..
¿Puedo usarlo en SSR como Next.js? / Can I use it in SSR like Next.js?
Sí. Internamente revisa si window existe antes de ejecutar el observer / Yes. Internally it checks if window exists before running the observer.
¿Cómo puedo aplicar una animación personalizada? / How can I apply a custom animation?
Usa transitionType="custom" y define tu clase con efectos CSS / Use transitionType="custom" and define your class with CSS effects.
📄 License / Licencia
👤 Author / Autor
Percy Chuzon 📧 [email protected] 🌐 https://percychuzon.com
💡 Tip
If you want more control, just set transitionType="custom" and style the image with CSS. It’s that simple.
Si deseas más control, usa transitionType="custom" y aplica tus estilos con CSS. Así de simple.
Happy loading! 🎉 / ¡Carga feliz! 🎉
