Navegadores compatibles
Puedes usar el atributo loading
para cargar imágenes de forma diferida sin necesidad de escribir un código de carga diferida personalizado o usar una biblioteca de JavaScript independiente. A continuación, te mostramos una demostración de la función:
En esta página, se explican los detalles para implementar la carga diferida en el navegador.
¿Por qué usar la carga diferida a nivel del navegador?
Según el Archivo HTTP, las imágenes son el tipo de recurso más solicitado para la mayoría de los sitios web y, por lo general, ocupan más ancho de banda que cualquier otro recurso. En el percentil 90, los sitios envían más de 5 MB de imágenes en computadoras y dispositivos móviles.
Anteriormente, había dos maneras de diferir la carga de imágenes fuera de pantalla:
- Usa la API de Intersection Observer.
- Usa controladores de eventos
scroll
,resize
oorientationchange
Cualquiera de las opciones puede permitir que los desarrolladores incluyan el comportamiento de carga diferida, y muchos desarrolladores compilaron bibliotecas de terceros para proporcionar abstracciones que son aún más fáciles de usar.
Sin embargo, con la carga diferida que admite directamente el navegador, no se necesita una biblioteca externa. La carga diferida a nivel del navegador también garantiza que la carga de imágenes siga funcionando incluso si el cliente inhabilita JavaScript. Sin embargo, ten en cuenta que la carga solo se aplaza cuando JavaScript está habilitado.
El atributo loading
Chrome carga imágenes con diferentes prioridades según su ubicación en relación con el viewport del dispositivo. Las imágenes debajo del viewport se cargan con una prioridad más baja, pero se recuperan a medida que se carga la página.
Puedes usar el atributo loading
para aplazar por completo la carga de imágenes fuera de la pantalla:
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
Estos son los valores admitidos para el atributo loading
:
lazy
: Difiere la carga del recurso hasta que alcance una distancia calculada desde el viewport.eager
: Es el comportamiento de carga predeterminado del navegador, que es lo mismo que no incluir el atributo y significa que la imagen se carga independientemente de dónde se encuentre en la página. Este es el valor predeterminado, pero puede ser útil configurarlo de forma explícita si tus herramientas agreganloading="lazy"
automáticamente cuando no hay un valor explícito o si tu lint se queja si no se establece de forma explícita.
Relación entre el atributo loading
y la prioridad de recuperación
El valor eager
es una instrucción para cargar la imagen como de costumbre, sin retrasar más la carga si la imagen está fuera de la pantalla. No carga la imagen más rápido que otra que no tiene un atributo loading
.
Si deseas aumentar la prioridad de recuperación de una imagen importante (por ejemplo, la imagen de LCP), usa Prioridad de recuperación con fetchpriority="high"
.
Una imagen con loading="lazy"
y fetchpriority="high"
todavía se retrasa mientras está fuera de la pantalla y, luego, se recupera con una prioridad alta cuando está casi dentro del viewport. Esta combinación no es realmente necesaria, ya que el navegador probablemente cargaría esa imagen con alta prioridad de todos modos.
Umbrales de distancia desde la ventana de visualización
Todas las imágenes que se pueden ver de inmediato sin desplazarse se cargan de forma normal. Las imágenes que se encuentran más abajo del viewport del dispositivo solo se recuperan cuando el usuario se desplaza cerca de ellas.
La implementación de la carga diferida de Chromium intenta garantizar que las imágenes fuera de pantalla se carguen con suficiente anticipación para que terminen de cargarse cuando el usuario las desplace, ya que las recupera mucho antes de que se vuelvan visibles en el viewport.
El umbral de distancia varía según los siguientes factores:
- Es el tipo de recurso de imagen que se recupera.
- El tipo de conexión real
Puedes encontrar los valores predeterminados de los diferentes tipos de conexión efectivos en la fuente de Chromium. Puedes experimentar con estos diferentes umbrales limitando la red en DevTools.
Umbrales mejorados de ahorro de datos y distancia desde el viewport
En julio de 2020, Chrome realizó mejoras significativas para alinear los umbrales de distancia de carga diferida de imágenes desde la ventana de visualización para satisfacer mejor las expectativas de los desarrolladores.
En conexiones rápidas (4G), reducimos los umbrales de distancia desde el viewport de Chrome de 3000px
a 1250px
y, en conexiones más lentas (3G o inferiores), cambiamos el umbral de 4000px
a 2500px
. Este cambio logra dos objetivos:
<img loading=lazy>
se comporta más cerca de la experiencia que ofrecen las bibliotecas de carga diferida de JavaScript.- Los nuevos umbrales de distancia desde la vista del puerto todavía significan que las imágenes probablemente se cargarán cuando el usuario se desplace hasta ellas.
A continuación, puedes encontrar una comparación entre los umbrales de distancia desde el viewport antiguos y los nuevos para una de nuestras demostraciones en una conexión rápida (4G):
y los nuevos umbrales en comparación con LazySizes (una biblioteca popular de carga diferida de JavaScript):
Asigna atributos de dimensión a tus imágenes
Mientras el navegador carga una imagen, no conoce de inmediato sus dimensiones, a menos que se especifiquen de forma explícita. Para permitir que el navegador reserve suficiente espacio en una página para las imágenes y evitar cambios de diseño disruptivos, te recomendamos agregar los atributos width
y height
a todas las etiquetas <img>
.
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
También puedes especificar sus valores directamente en un estilo intercalado:
<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">
La práctica recomendada de configurar dimensiones se aplica a las etiquetas <img>
sin importar si las cargas de forma diferida. Sin embargo, la carga diferida puede hacerla más importante.
La carga diferida en Chromium se implementa de una manera que aumenta la probabilidad de que las imágenes se carguen en cuanto son visibles, pero aún existe la posibilidad de que no se carguen en el momento adecuado. Si eso sucede, no especificar width
y height
en tus imágenes aumenta su impacto en el cambio de diseño acumulativo. Si no puedes especificar las dimensiones de las imágenes, la carga diferida puede ahorrar recursos de red con el riesgo de tener estos cambios de diseño aumentados.
En la mayoría de los casos, las imágenes se cargan de forma diferida si no especificas las dimensiones, pero hay algunos casos extremos que debes tener en cuenta. Si no se especifican width
y height
, las dimensiones de la imagen se establecen de forma predeterminada en 0 × 0 píxeles. Si tienes una galería de imágenes, el navegador podría decidir que todas caben dentro del viewport al principio, ya que cada imagen no ocupa espacio y no se envía ninguna imagen fuera de la pantalla. En este caso, el navegador decide cargar todo, lo que hace que la página se cargue más lento.
Para ver un ejemplo de cómo funciona loading
con una gran cantidad de imágenes, consulta esta demostración.
También puedes realizar cargas diferidas de imágenes que hayas definido con el elemento <picture>
:
<picture>
<source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
<img src="photo.jpg" loading="lazy">
</picture>
Aunque el navegador decide qué imagen cargar desde cualquiera de los elementos <source>
, solo debes agregar loading
al elemento <img>
de resguardo.
Carga siempre de forma anticipada las imágenes visibles en el primer viewport
Para las imágenes que son visibles cuando el usuario carga la página por primera vez, y en especial para las imágenes de LCP, usa la carga anticipada predeterminada del navegador para que estén disponibles de inmediato. Para obtener más información, consulta Los efectos en el rendimiento de una carga diferida excesiva.
Usa loading=lazy
solo para imágenes fuera del viewport inicial. El navegador no puede cargar de forma diferida una imagen hasta que sepa dónde debe estar en la página, lo que hace que se cargue más lentamente.
<!-- visible in the viewport -->
<img src="product-1.jpg" alt="..." width="200" height="200">
<img src="product-2.jpg" alt="..." width="200" height="200">
<img src="product-3.jpg" alt="..." width="200" height="200">
<!-- offscreen images -->
<img src="product-4.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-5.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-6.jpg" loading="lazy" alt="..." width="200" height="200">
Degradación elegante
Los navegadores que no admiten el atributo loading
lo ignoran. No obtienen los beneficios de la carga diferida, pero no hay un impacto negativo si se incluye.
Preguntas frecuentes
Algunas preguntas frecuentes sobre la carga diferida a nivel del navegador
¿Puedo cargar imágenes de forma diferida automáticamente en Chrome?
Anteriormente, Chromium cargaba de forma diferida automáticamente las imágenes que se adaptaban bien a la demora si el modo Lite estaba habilitado en Chrome para Android y no se proporcionaba el atributo loading
o se configuraba como loading="auto"
. Sin embargo, el modo Lite y loading="auto"
dejaron de estar disponibles y no hay planes para proporcionar la carga diferida automática de imágenes en Chrome.
¿Puedo cambiar la proximidad de una imagen al viewport antes de que se cargue?
Estos valores están codificados y no se pueden cambiar a través de la API. Sin embargo, es posible que cambien en el futuro, a medida que los navegadores experimenten con diferentes variables y distancias límite.
¿Las imágenes de fondo de CSS pueden usar el atributo loading
?
No, solo puedes usarlo con etiquetas <img>
.
¿Puede loading
funcionar con imágenes en el viewport que no son visibles de inmediato?
El uso de loading="lazy"
puede evitar que se carguen imágenes cuando no son visibles, pero están dentro de la distancia calculada.
Estas imágenes pueden estar detrás de un carrusel o ocultas por CSS para ciertos tamaños de pantalla. Por ejemplo, Chrome, Safari y Firefox no cargan imágenes con diseño display: none;
, ya sea en el elemento de imagen o en un elemento superior. Sin embargo, otras técnicas de ocultación de imágenes, como el uso de diseño opacity:0
, aún hacen que el navegador cargue la imagen. Siempre prueba tu implementación de forma exhaustiva para asegurarte de que funcione según lo previsto.
Chrome 121 cambió el comportamiento de las imágenes de desplazamiento horizontal, como los carruseles. Ahora usan los mismos umbrales que el desplazamiento vertical. Esto significa que, en el caso de uso del carrusel, las imágenes se cargarán antes de que sean visibles en la ventana de visualización. Esto significa que es menos probable que el usuario note la carga de imágenes, pero a costa de más descargas. Usa la demostración de carga diferida horizontal para comparar el comportamiento de Chrome con el de Safari y Firefox.
¿Qué sucede si ya uso una biblioteca o una secuencia de comandos de terceros para cargar imágenes de forma diferida?
Con la compatibilidad total de la carga diferida integrada en los navegadores modernos, es probable que no necesites una biblioteca o secuencia de comandos de terceros para cargar imágenes de forma diferida.
Uno de los motivos para seguir usando una biblioteca de terceros junto con loading="lazy"
es proporcionar un polyfill para navegadores que no admiten el atributo o para tener más control sobre cuándo se activa la carga diferida.
¿Cómo manejo los navegadores que no admiten la carga diferida?
La carga diferida de imágenes a nivel del navegador es compatible con todos los navegadores principales y se recomienda para la mayoría de los casos de uso, ya que elimina la necesidad de dependencias adicionales en JavaScript.
Sin embargo, si necesitas admitir más navegadores o deseas tener más control sobre los umbrales de carga diferida, puedes usar una biblioteca de terceros para cargar imágenes de forma diferida en tu sitio.
Puedes usar la propiedad loading
para detectar si un navegador admite la función:
if ('loading' in HTMLImageElement.prototype) {
// supported in browser
} else {
// fetch polyfill/third-party library
}
Por ejemplo, lazysizes es una biblioteca popular de carga diferida de JavaScript. Puedes detectar la compatibilidad con el atributo loading
para cargar tamaños diferidos como una biblioteca de resguardo solo cuando loading
no sea compatible. Esto funciona de la siguiente manera:
- Reemplaza
<img src>
por<img data-src>
para evitar una carga inmediata en navegadores no compatibles. Si el atributoloading
es compatible, cambiadata-src
porsrc
. - Si no se admite
loading
, carga un resguardo de tamaños diferidos e inícialo con la claselazyload
para indicar qué imágenes realizar la carga diferida:
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">
<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">
<script>
if ('loading' in HTMLImageElement.prototype) {
const images = document.querySelectorAll('img[loading="lazy"]');
images.forEach(img => {
img.src = img.dataset.src;
});
} else {
// Dynamically import the LazySizes library
const script = document.createElement('script');
script.src =
'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
document.body.appendChild(script);
}
</script>
Esta es una demostración de este patrón. Pruébala en un navegador más antiguo para ver el resguardo en acción.
¿La carga diferida de iframes también es compatible con los navegadores?
Navegadores compatibles
También se estandarizó <iframe loading=lazy>
. Esto te permite cargar iframes de manera diferida con el atributo loading
. Para obtener más información, consulta Es hora de cargar iframes fuera de la pantalla de forma diferida.
¿Cómo afecta la carga diferida a nivel del navegador a los anuncios en una página web?
Todos los anuncios que se muestran al usuario como imágenes o iframes se cargan de forma diferida, al igual que cualquier otra imagen o iframe.
¿Cómo se manejan las imágenes cuando se imprime una página web?
Todas las imágenes y los iframes se cargan de inmediato cuando se imprime la página. Consulta el problema #875403 para obtener más detalles.
¿Lighthouse reconoce la carga diferida a nivel del navegador?
Lighthouse 6.0 y un factor más alto en los enfoques para la carga diferida de imágenes fuera de pantalla que pueden usar diferentes umbrales, lo que les permite pasar la auditoría Defer offscreen images.
Carga imágenes de forma diferida para mejorar el rendimiento
La compatibilidad del navegador con la carga diferida de imágenes puede facilitar mucho la mejora del rendimiento de tus páginas.
¿Notas algún comportamiento inusual con esta función habilitada en Chrome? Informa un error.