Aplazar imágenes fuera de pantalla en móviles: Guía de carga diferida nativa

Carga diferida nativa, content-visibility y por qué aplazar imágenes con JavaScript es peso muerto

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-10

Aplazamiento de imágenes móviles: el estándar

Las páginas móviles compiten por conexiones limitadas y una CPU limitada. Cada imagen fuera de pantalla que cargas por adelantado roba ancho de banda a las imágenes y scripts que realmente importan para el pintado inicial.

Última revisión por Arjen Karel en marzo de 2026

1. Aplazar imágenes fuera de pantalla en móviles: carga diferida nativa

Cuando un navegador carga una página, abre un número limitado de conexiones paralelas (dependiendo de muchos factores, pero 6 por dominio es un promedio común). Si estas conexiones se utilizan para descargar imágenes fuera de pantalla (por ejemplo, un logotipo en el pie de página o una diapositiva de carrusel), la descarga de recursos críticos (normalmente la imagen LCP, scripts y fuentes importantes) competirá por espacios y ancho de banda. Esto es contención de red y degrada directamente tus Core Web Vitals.

Al aplazar las imágenes fuera de pantalla utilizando el atributo nativo loading, priorizas lo que importa. El navegador solo obtiene lo que es inmediatamente visible, reservando ancho de banda para los recursos que impactan en el Largest Contentful Paint (LCP) y el First Contentful Paint (FCP). La carga diferida nativa descarga esta priorización al propio mecanismo del navegador, lo que es más rápido y elimina la necesidad de bibliotecas de carga diferida de JavaScript.

Implementación

Para todas las imágenes debajo del viewport inicial ("el pliegue") añade el atributo loading="lazy".

<!-- Standard Deferred Image -->
<img src="product-detail.jpg"
     loading="lazy"
     alt="Side view of the chassis"
     width="800"
     height="600"
     decoding="async">

Los atributos width y height son esenciales. Sin ellos, el navegador no puede reservar espacio antes de que la imagen se cargue, lo que provoca un cambio de diseño (Cumulative Layout Shift, CLS). El 62% de las páginas móviles todavía no establecen dimensiones explícitas en al menos una imagen.

Cómo funciona la carga diferida en móviles: La heurística del navegador

La carga diferida nativa es superior a las soluciones de JavaScript porque el navegador ajusta el umbral de carga (cuando se activa la descarga de una imagen) en función del Tipo de Conexión Efectiva (ECT).

  • En 4G/WiFi: El motor Blink (Chrome/Edge) utiliza un umbral conservador de unos 1.250px. Asume baja latencia y obtiene la imagen solo cuando el usuario se desplaza relativamente cerca.
  • En 3G/Slow-2G: El umbral se amplía a unos 2.500px. El navegador inicia la solicitud mucho antes para compensar los altos tiempos de ida y vuelta, de modo que la imagen esté lista antes de que el usuario la haga visible al desplazarse.

Según el Web Almanac de 2025, la página móvil mediana carga 15 imágenes que suman un total de 911 KB. Solo alrededor del 26% de esas imágenes usan loading="lazy". El resto se carga de forma anticipada, compitiendo por las mismas conexiones limitadas. En una conexión móvil 4G típica, eso significa que la imagen LCP se queda esperando detrás de una docena de imágenes que el usuario no verá durante varios segundos.

Excepción Crítica: El candidato a LCP

Una regresión de rendimiento común: aplicar loading="lazy" al elemento Largest Contentful Paint (típicamente la imagen principal o hero image). Esto retrasa la obtención hasta que se completa el layout.

Las investigaciones de Google muestran que la carga diferida de la imagen LCP añade 624 ms a la mediana de LCP. Ese no es un riesgo teórico. El 17% de las páginas móviles todavía cometen este error según el Web Almanac de 2025. Si Lighthouse señala esto, consulta cómo solucionar la advertencia de LCP de carga diferida.

La imagen LCP debe cargarse de forma anticipada (eager) y priorizarse:

<!-- Hero Image: Eager and Prioritized -->
<img src="hero.jpg"
     alt="Summer Collection"
     width="1200"
     height="800"
     loading="eager"
     fetchpriority="high">

No combines loading="lazy" con fetchpriority="high". Se contradicen entre sí: lazy le dice al navegador que espere, high le dice que se dé prisa. El navegador ignora la sugerencia de prioridad cuando lazy está establecido. Para obtener más información sobre cómo los navegadores priorizan los recursos, consulta la guía de priorización de recursos.

2. Complejidades móviles: Viewport y táctil

Los viewports móviles no son estáticos. El área visible cambia a medida que el usuario se desplaza, rota el dispositivo o hace que la barra de URL se retraiga. Aquí es donde la carga diferida nativa tiene una ventaja real sobre las soluciones de JavaScript.

  • El Viewport: El área rectangular visible de la ventana del navegador. En dispositivos móviles, esto es dinámico; cambia de dimensiones según la orientación del dispositivo (vertical vs. horizontal) y el estado de la interfaz del navegador (retracción de las barras de URL).
  • El Pliegue (The Fold): El borde inferior exacto del viewport. Es el umbral que separa el contenido visible del contenido fuera de pantalla.
  • Por encima del pliegue (Above the Fold): Cualquier contenido visible inmediatamente al cargar la página sin desplazarse. Las imágenes aquí son críticas y nunca deben cargarse de forma diferida.
  • Por debajo del pliegue (Below the Fold): Cualquier contenido ubicado verticalmente más allá del pliegue. Este contenido no es crítico y debe aplazarse hasta que el usuario se desplace cerca de él.

El Viewport dinámico

En los navegadores móviles, la altura del viewport (vh) es fluida. A medida que el usuario inicia un desplazamiento táctil, la barra de URL y los controles de navegación a menudo se retraen, cambiando el tamaño del área visible.

Las bibliotecas de carga diferida de JavaScript normalmente calculan la altura del viewport (window.innerHeight) una vez al cargar la página. Cuando los navegadores móviles cambian dinámicamente el tamaño del área visible ocultando la barra de URL durante un desplazamiento, los métodos de JavaScript continúan usando el valor de altura antiguo y más pequeño. Las imágenes permanecen descargadas incluso cuando ingresan al viewport expandido, causando marcadores de posición en blanco para los visitantes.

El motor de layout interno del navegador rastrea el viewport visual automáticamente, por lo que los activadores de carga diferida nativa se disparan independientemente de los cambios de tamaño del viewport. Esta es una de las razones para preferir la carga diferida nativa sobre cualquier alternativa de JavaScript.

3. Decodificación de imágenes en móviles y limitación de CPU

Los dispositivos móviles tienen una CPU limitada y la decodificación de imágenes en el móvil puede ser relativamente lenta y costosa. Convertir un JPEG en un mapa de bits requiere muchos ciclos de CPU. En un procesador móvil, decodificar una secuencia de imágenes más grandes puede bloquear el hilo principal (main thread) durante 50 ms a 100 ms cada una, lo que causa latencia de entrada.

La solución: content-visibility

La propiedad CSS content-visibility: auto actúa como renderizado diferido. Indica al navegador que omita por completo las fases de layout y pintado (painting) para los elementos fuera de pantalla. El elemento existe en el DOM, pero no existe en el Render Tree hasta que se acerca al viewport.

Debido a que esta optimización funciona al omitir el renderizado del subárbol de un elemento, no puedes aplicarla directamente a una etiqueta <img> (que no tiene subárbol). Aplica content-visibility al contenedor del producto o a la tarjeta de imagen que aloja las imágenes y su contenido:

@media (max-width: 768px) {
    .image-card, .product-card {
        /* Skip rendering of the container and its children */
        content-visibility: auto;

        /* Essential: Prevents container from collapsing to 0px height */
        contain-intrinsic-size: auto 300px;
    }
}

Esto asegura que, incluso si se descarga una imagen, el navegador no paga el coste de layout/pintado hasta que el usuario se desplaza realmente hacia ella.

content-visibility alcanzó el estado Baseline en septiembre de 2024 cuando Safari 18 implementó su soporte. Ahora funciona en el 93% de los navegadores a nivel mundial. Los benchmarks de Google muestran un aumento de rendimiento de renderizado de 7x en la carga inicial de páginas con muchas secciones fuera de pantalla.

Si deseas verificar la mejora de renderizado en dispositivos reales, el Real User Monitoring te mostrará el impacto real de INP y LCP en todo tu tráfico móvil. En los sitios monitoreados por CoreDash, las páginas que usan content-visibility: auto en cuadrículas de productos muestran un INP aproximadamente un 15% mejor en dispositivos móviles en comparación con las páginas que no lo tienen.

4. Metodologías heredadas: Por qué evitarlas

Antes de que loading="lazy" tuviera soporte en los navegadores, JavaScript era la única opción. Con la carga diferida nativa en un 95% de soporte global, estos métodos de JavaScript son deuda técnica. Elimínalos.

La era de los manejadores de Scroll (2010 a 2016)

Las primeras implementaciones vinculaban listeners de eventos al evento scroll.

// Obsolete: do not use
window.addEventListener('scroll', () => {
    images.forEach(img => {
        if (img.getBoundingClientRect().top < window.innerHeight) {
            img.src = img.dataset.src;
        }
    });
});

Bloqueo del hilo principal: El evento scroll se dispara docenas de veces por segundo. La ejecución de lógica y el cálculo de layout (getBoundingClientRect) durante el desplazamiento activo provoca caídas de frames (jank).

Layout Thrashing: Consultar las propiedades geométricas fuerza al navegador a recalcular el layout de forma síncrona, una operación computacionalmente costosa en las CPU móviles.

La era de IntersectionObserver (2016 a 2019)

La API IntersectionObserver mejoró el rendimiento al observar de forma asíncrona los cambios en la visibilidad de los elementos.

// Legacy: prefer native loading="lazy" where possible
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            observer.unobserve(img);
        }
    });
});

Dependencia de Script: Requiere la ejecución de JavaScript. Si el hilo principal está ocupado hidratando un framework (React/Vue), las imágenes permanecen descargadas incluso si están en el viewport.

Falta de consciencia de la red: A diferencia de la carga nativa, IntersectionObserver utiliza márgenes fijos (por ejemplo, rootMargin: '200px'). No expande automáticamente su búfer en redes lentas, lo que provoca destellos en blanco para los usuarios con conexiones deficientes.

Para obtener una descripción general completa de las técnicas de optimización de imágenes más allá de la carga diferida, o para aprender sobre cómo aplazar imágenes de fondo CSS (que loading="lazy" no cubre), consulta esas guías dedicadas.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Find out what is actually slow.

I map your critical rendering path using real field data. You get a prioritized fix list, not a Lighthouse report.

Get the audit
Aplazar imágenes fuera de pantalla en móviles: Guía de carga diferida nativaCore Web Vitals Aplazar imágenes fuera de pantalla en móviles: Guía de carga diferida nativa