Lazy loading en imágenes y vídeos: paso a paso para no romper tu web

La técnica de lazy loading (cargar recursos solo cuando son necesarios) es una de las formas más efectivas de mejorar la velocidad percibida y reducir el consumo de datos. Pero si se aplica sin criterio puede perjudicar tus Core Web Vitals, romper el SEO o impedir que usuarios vean contenido crítico. Aquí tienes una guía práctica y ordenada para aplicar lazy loading a imágenes y vídeos sin «cargar» problemas en tu web.

Qué es y cuándo usar lazy loading

Lazy loading pospone la descarga de recursos (imágenes, iframes, vídeos) hasta que están cerca de la ventana gráfica o el usuario los necesita. Es ideal para galerías largas, imágenes bajo el fold y iframes de terceros. No es buena idea para elementos que forman parte del contenido crítico visible al cargar la página (hero/LCP). Usa lazy loading para reducir bytes iniciales y mejorar tiempo de carga percibido.

Paso 1 — Prioriza lo crítico: no lances tu LCP

Antes de aplicar lazy loading identifica qué elemento es el LCP (Largest Contentful Paint). Nunca pongas loading="lazy" en la imagen o vídeo que probablemente sea el LCP; eso retrasará su descarga y empeorará la métrica. Para elementos críticos usa fetchpriority="high" o preloads adecuados y deja el lazy para el resto.

Paso 2 — Usa lazy nativo cuando baste

Hoy en día la forma más sencilla y robusta es confiar en el atributo nativo loading="lazy" en <img> y <iframe>; los navegadores lo ignoran si no lo soportan, y evita dependencias externas. Ejemplo mínimo:

<img src="foto-800.jpg" alt="Descripción" loading="lazy" width="800" height="600">
<iframe src="https://player.example" loading="lazy" width="560" height="315"></iframe>

El lazy nativo es sencillo y eficiente para la mayoría de casos; úsalo siempre que no necesites un control más fino.

Paso 3 — Control fino con IntersectionObserver (mejor cobertura)

Para escenarios avanzados —placeholders LQIP, carga diferida de background-image, o vídeos que deben arrancar solo cuando el usuario se acerca— utiliza IntersectionObserver. Patrón habitual: deja en el src una imagen de baja calidad o data-src vacío y, al intersectar, sustituyes por la url real y remueves la observación. Ejemplo básico:

const imgs = document.querySelectorAll('img[data-src]');
if ('IntersectionObserver' in window) {
  const io = new IntersectionObserver((entries, obs) => {
    entries.forEach(e => {
      if (e.isIntersecting) {
        const img = e.target;
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
        obs.unobserve(img);
      }
    });
  }, { rootMargin: '200px 0px' });
  imgs.forEach(i => io.observe(i));
} else {
  imgs.forEach(i => i.src = i.dataset.src);
}

Ajusta rootMargin para cargar con antelación si quieres evitar demoras al hacer scroll rápido.

Paso 4 — Vídeos y embeds: poster, preload y carga on-demand

Para <video> evita autoplay y usa poster para mostrar un placeholder; marca preload="metadata" o none y carga la fuente real con IntersectionObserver o al click del usuario. Para embeds (YouTube/Vimeo) lo ideal es un placeholder con play que inyecta el <iframe> cuando el usuario pulsa o cuando está muy cerca del viewport. Esto reduce solicitudes a terceros y evita impactos en memoria y Core Web Vitals.

Paso 5 — Responsive, dimensiones y evitar layout shifts

Para evitar Cumulative Layout Shift (CLS) siempre especifica width y height en las imágenes o usa aspect-ratio CSS para reservar espacio. Emplea srcset y sizes para entregar imágenes adaptadas al dispositivo y así reducir bytes. Ejemplo:

<img src="img-800.jpg"
 srcset="img-400.jpg 400w, img-800.jpg 800w, img-1200.jpg 1200w"
 sizes="(max-width:600px) 100vw, 50vw"
 width="1200" height="800"
 loading="lazy" alt="...">

Paso 6 — Accesibilidad y SEO: alt + noscript + SSR

No sacrifiques accesibilidad: cada <img> necesita alt. Para SEO y bots considera un noscript con la imagen final para que los rastreadores y usuarios sin JS vean el contenido. Si usas SSR, renderiza la imagen crítica server-side y lazy-load el resto.

Ejemplo de fallback:

<noscript><img src="imagen.jpg" alt="..."></noscript>

Paso 7 — Qué comprobar y herramientas

Mide el impacto con Lighthouse y los reportes de Core Web Vitals: compara LCP, CLS y First Contentful Paint antes/después. Revisa si tus cambios bloquean recursos críticos o si algún recurso lazy está retrasando interacciones. Usa DevTools Network y el informe de campo para validar.

Errores comunes que rompen la experiencia

  1. Lazy en hero/LCP (peor LCP). 2) No reservar espacio (CLS). 3) Depender solo de JS sin noscript. 4) Cargar iframes de terceros sin lazy o placeholder (impacto en memoria y TTFB). 5) Usar loading="lazy" en todos los elementos sin distinguir prioridad. Evítalos priorizando y testeando.

Conclusión y checklist rápido

Prioriza: identifica tu LCP y no lo laces. Usa loading="lazy" para la mayoría; recurre a IntersectionObserver para casos avanzados. Pre-reserva espacio con width/height o aspect-ratio, usa srcset/sizes, añade poster para vídeos y placeholder+click para embeds. Añade noscript y alt para accesibilidad y SEO. Mide con Lighthouse y field data: si el lazy mejora la experiencia, perfecto; si empeora LCP o genera CLS, reevalúa y ajusta prioridades.

¿Quieres que te genere ejemplos listos para copiar (HTML + CSS + JS) para: 1) galería de imágenes con LQIP, 2) vídeo lazy con poster, y 3) embed de YouTube on-demand?

Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.