Carga diferida de imágenes a nivel del navegador para la Web

Navegadores compatibles

  • Chrome: 77
  • Borde: 79.
  • Firefox: 75.
  • Safari: 15.4.

Puedes usar el atributo loading para realizar cargas diferidas de imágenes sin necesidad de escribir código personalizado de carga diferida o usar una biblioteca de JavaScript independiente Este es un demostración de la función:

Las imágenes de carga diferida se cargan a medida que el usuario se desplaza por la página.

En esta página, se explican los detalles de la implementación de 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, consumen más ancho de banda que cualquier otro recurso. En el percentil 90, los sitios enviar más de 5 MB de imágenes en computadoras y dispositivos móviles.

Anteriormente, había dos formas de diferir la carga de imágenes fuera de pantalla:

Ambas opciones permiten a los desarrolladores incluir un comportamiento de carga diferida desarrolladores compilaron bibliotecas de terceros para brindar abstracciones sea aún más fácil de usar.

Sin embargo, dado que el navegador admite la carga diferida directamente, 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 las imágenes con diferentes prioridades según su ubicación en relación con el viewport del dispositivo. Las imágenes debajo de la viewport se cargan con una pero se recuperan a medida que se carga la página.

Puedes usar el atributo loading para diferir por completo la carga del contenido fuera de la pantalla imágenes:

<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 un valor. distancia calculada desde el viewport.
  • eager: Comportamiento de carga predeterminado del navegador, que es el mismo que no. incluido el atributo, y significa que la imagen se carga independientemente de dónde se encuentre ubicado en la página. Este es el valor predeterminado, pero puede ser útil establecer de forma explícita si tus herramientas agregan loading="lazy" automáticamente cuando no hay un valor explícito o si tu linter genera un reclamo si no se estableció explícitamente.

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 retrasos la carga continúa si la imagen está fuera de la pantalla. No carga la imagen más rápido que otra imagen que no tenga un atributo loading.

Si quieres aumentar la prioridad de recuperación de una imagen importante (por ejemplo, la imagen de LCP), usa la Prioridad de recuperación con fetchpriority="high"

Una imagen con loading="lazy" y fetchpriority="high" todavía se retrasa. se encuentra fuera de la pantalla y, luego, se recupera con una prioridad alta cuando está a punto de el viewport. Esta combinación no es realmente necesaria porque el navegador probablemente cargue la imagen con prioridad alta de todos modos.

Umbrales de distancia desde la viewport

Todas las imágenes que se pueden ver de inmediato sin necesidad de desplazarse se cargan de forma normal. Imágenes por debajo del viewport del dispositivo solo se recuperan cuando el usuario se desplaza cerca de él.

La implementación de Chromium de carga diferida intenta garantizar que las imágenes fuera de pantalla Se cargan con suficiente antelación como para que, cuando el usuario se desplace, termine de cargarse. obteniéndolos mucho antes de que sean visibles en el viewport.

El umbral de distancia varía según los siguientes factores:

Puedes encontrar los valores predeterminados para los diferentes tipos de conexiones efectivas en la fuente de Chromium. Puedes experimentar con estos diferentes umbrales limitar la red en Herramientas para desarrolladores.

Ahorro de datos mejorado y umbrales de distancia desde la vista del puerto

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 las conexiones rápidas (4G), redujimos los umbrales de distancia desde la ventana de visualización de Chrome de 3000px a 1250px. En las conexiones más lentas (3G o inferior), cambiamos el umbral de 4000px a 2500px. Con este cambio, se logran dos cosas:

  • <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, encontrarás 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):

Los umbrales nuevos y mejorados para la carga diferida de imágenes reducen los umbrales de distancia desde la ventana gráfica para conexiones rápidas de 3,000 px a 1,250 px.
Comparación entre los umbrales más antiguos y más nuevos que se usan para la carga diferida a nivel del navegador.

y los nuevos umbrales en comparación con LazySizes (una popular biblioteca de carga diferida de JavaScript):

Los nuevos umbrales de distancia desde la ventana de visualización en Chrome cargan 90 KB de imágenes, en comparación con la carga LazySizes en 70 KB en las mismas condiciones de red.
Comparación de los umbrales usados para la carga diferida en Chrome y LazySizes.

Asigna atributos de dimensiones a tus imágenes

Mientras el navegador carga una imagen, no sabe inmediatamente cuál es dimensiones, a menos que se especifiquen explícitamente. Para permitir que el navegador se reserve espacio suficiente en una página para 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>, independientemente de lo siguiente: ya sea que las cargues de forma diferida, esta puede ser más importante.

La carga diferida en Chromium se implementa de una manera que aumenta las probabilidades de que se muestren las imágenes se carguen en cuanto sean visibles, pero existe la posibilidad de que no se cargan en el momento adecuado. Si eso sucede, sin especificar width ni height en tus imágenes aumenta su impacto en el Cambio de diseño acumulado. Si No puedes especificar las dimensiones dimensiones, su carga diferida puede ahorrar recursos aunque corren el riesgo de que se produzcan mayores cambios en el diseño.

En la mayoría de los casos, las imágenes se cargan de forma diferida si no especificas dimensiones, hay algunos casos límite que debes conocer. Sin width ni height se especifica, las dimensiones de la imagen predeterminadas son de 0 × 0 píxeles. Si tienes una galería de imágenes, el navegador podría decidir que todas caben dentro de la ventana de visualización en el ya que cada imagen no ocupa espacio y ninguna imagen se desplaza fuera de la pantalla. En en este caso, el navegador decide cargar todo y hace que la página se cargue más lentamente.

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 <source> solo debes agregar loading al elemento <img> de resguardo.

Siempre se deben cargar las imágenes con anticipación en el primer viewport.

Para imágenes que están visibles cuando el usuario carga la página por primera vez y, en especial, Para imágenes LCP, utiliza la carga inmediata predeterminada del navegador para que puedan estar disponibles. de inmediato. Para obtener más información, consulta Efectos en el rendimiento de una carga diferida.

Usa loading=lazy solo para imágenes fuera del viewport inicial. El navegador No puede realizar una carga diferida de una imagen hasta que sepa dónde debería estar en la página. lo que hace que se carguen más lento.

<!-- 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 correcta

Los navegadores que no admiten el atributo loading lo ignoran. No reciben los beneficios de la carga diferida, pero no hay un impacto negativo si la incluye.

Preguntas frecuentes

Algunas preguntas frecuentes sobre la carga diferida a nivel del navegador

¿Puedo realizar una carga diferida de imágenes en Chrome automáticamente?

Anteriormente, Chromium cargaba automáticamente de forma diferida las imágenes que eran adecuadas se pospondrá si el modo básico estaba habilitado en Chrome para Android y el atributo loading no era se proporciona o se establece en loading="auto". Sin embargo, El modo lite y loading="auto" dejaron de estar disponibles y no hay planes de proporcionar automáticamente una carga diferida de imágenes en Chrome.

¿Puedo cambiar qué tan cerca debe estar una imagen del viewport antes de que se cargue?

Estos valores están codificados y no se pueden cambiar a través de la API. Sin embargo, podría cambiar en el futuro, a medida que los navegadores experimenten con diferentes distancias y variables.

¿Las imágenes de fondo de CSS pueden usar el atributo loading?

No, solo puedes usarlo con etiquetas <img>.

Usar loading="lazy" puede impedir que se carguen imágenes cuando no lo están visibles, pero que estén dentro de la distancia calculada. Estas imágenes pueden estar detrás de un carrusel, o bien ocultas por CSS para ciertas pantallas tamaños. Por ejemplo, Chrome, Safari y Firefox no cargan imágenes con Estilos display: none;, ya sea en el elemento de imagen o en un elemento superior . Sin embargo, hay otras técnicas de ocultamiento de imágenes, como el uso de opacity:0 estilo, hará que el navegador cargue la imagen. Prueba siempre tu implementación exhaustiva para garantizar que funciona 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, para el caso de uso de carrusel, las imágenes se cargarán antes de que sean visibles en el viewport. Esto significa que es menos probable que el usuario note la carga de la imagen, 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 de terceros o una secuencia de comandos para realizar la carga diferida de imágenes?

Gracias a la compatibilidad total con la carga diferida integrada en los navegadores modernos, probablemente no necesitas una biblioteca o una secuencia de comandos de terceros para la carga diferida de imágenes.

Un motivo para seguir usando una biblioteca de terceros junto con loading="lazy" es proporcionar un polyfill para los navegadores que no admitan el atributo tienen más control sobre cuándo se activa la carga diferida.

¿Cómo controlo los navegadores que no admiten la carga diferida?

La carga diferida de imágenes en el nivel del navegador es compatible con todos los navegadores principales y se recomienda en la mayoría de los casos de uso para quitar la necesidad de dependencias adicionales en JavaScript.

Sin embargo, si necesitas admitir más navegadores o quieres tener más control sobre los umbrales de carga diferida, puedes usar una biblioteca de terceros para realizar cargas diferidas de imágenes en tu sitio.

Puedes usar la propiedad loading para detectar si un navegador admite el atributo:

if ('loading' in HTMLImageElement.prototype) {
  // supported in browser
} else {
  // fetch polyfill/third-party library
}

Por ejemplo, lazysizes es una función popular Biblioteca de carga diferida de JavaScript Puedes detectar compatibilidad con loading para cargar lazysizes como una biblioteca de resguardo solo cuando loading no es no es compatible. Esto funciona de la siguiente manera:

  • Reemplaza <img src> por <img data-src> para evitar una carga inmediata en navegadores no compatibles. Si se admite el atributo loading, intercambia data-src para src.
  • Si no se admite loading, carga un resguardo de tamaños diferidos y, luego, inicia con la clase lazyload 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ébalo en un navegador anterior para ver el resguardo en acción.

¿Los navegadores también admiten la carga diferida de iframes?

Navegadores compatibles

  • Chrome: 77
  • Borde: 79.
  • Firefox: 121
  • Safari: 16.4.

También se estandarizó <iframe loading=lazy>. Esto te permite realizar una carga diferida de iframes con loading. . Para obtener más información, consulta el artículo Es momento de realizar una carga diferida de los iframes fuera de pantalla.

¿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 de carga diferida, al igual que cualquier otro 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 problema #875403 para obtener más detalles.

¿Lighthouse reconoce la carga diferida a nivel del navegador?

Lighthouse 6.0 y versiones posteriores tienen en cuenta de carga diferida de imágenes fuera de pantalla que usan diferentes umbrales permitiéndoles pasar Auditoría de Aplaza las imágenes fuera de pantalla

Imágenes de carga diferida para mejorar el rendimiento

La compatibilidad del navegador con la carga diferida de imágenes puede facilitarte mucho más la tarea para mejorar el rendimiento rendimiento.

¿Notas algún comportamiento inusual con esta función habilitada en Chrome? ¡Informa un error!