Como Integrar Lazy-Loading Nativo de Imágenes En Tus Proyectos Web

by Luigi Nori Date: 04-08-2020 lazy loading chrome nativo


¡El soporte nativo de lazy-loading en imágenes está ahora soportado en la web! Mira esta demostración de la función

A partir de la versión 76 de Chrome, puedes usar el atributo para hacer lazy-loading en imágenes sin necesidad de escribir un código personalizado para el lazy-loading o usar una librería JavaScript separada. Sumerjámonos en los detalles.

Compatibilidad del navegador 

<img loading=lazy>  es soportado por los navegadores más populares de cromo (Chrome, Edge, Opera) y Firefox. La aplicación de WebKit (Safari) está en progresocaniuse.com tiene información detallada sobre el soporte cross-browser. Los navegadores que no soportan el atributo de carga simplemente lo ignoran sin efectos secundarios.

¿Por qué el lazy-loading nativo? 

De acuerdo con HTTPArchive, Las imágenes son el tipo de activo más solicitado por la mayoría de los sitios web y suelen ocupar más ancho de banda que cualquier otro recurso. En el percentil 90, los sitios envían alrededor de 4.7 MB de imágenes en el escritorio y en el móvil. Eso es un montón de fotos de gatos.

Actualmente, hay dos maneras de aplazar la carga de las imágenes fuera de la pantalla:

Cualquiera de las opciones puede permitir a los desarrolladores incluir la funcionalidad de carga lenta lazy-loading, y muchos desarrolladores han construido bibliotecas de terceros para proporcionar abstracciones que son aún más fáciles de usar. Sin embargo, con la carga lenta lazy-loading soportada directamente por el navegador, no hay necesidad de una biblioteca externa. La carga lenta nativa también asegura que la carga diferida de imágenes siga funcionando incluso si JavaScript está desactivado en el cliente.

El atributo de carga "loading" 

Hoy en día, Chrome ya carga imágenes con diferentes prioridades dependiendo de dónde se encuentren con respecto a la vista del dispositivo. Las imágenes que están debajo del visor se cargan con una prioridad menor, pero se siguen recuperando lo antes posible.

En Chrome 76+, puedes usar el atributo de carga loading para retrasar completamente la carga de las imágenes fuera del marco de la pantalla a las que se puede acceder mediante el desplazamiento:

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

Aquí están los valores soportados para el atributo de carga:

  • auto : Comportamiento de carga lenta (lazy-loading) del navegador, que es lo mismo que no incluir el atributo.
  • lazy : Pospone la carga del recurso hasta que alcance una distancia calculada del punto de vista.
  • eager : Carga el recurso inmediatamente, sin importar dónde se encuentre en la página.

Atención: Aunque está disponible en Chrome, el valor automático no se menciona en la especificación. Como puede estar sujeto a cambios, recomendamos no usarlo hasta que se incluya.

Umbrales de distancia desde el punto de vista de la visión Distance-from-viewport 

Todas las imágenes que están por encima del pliegue, es decir, inmediatamente visibles sin desplazamiento, se cargan normalmente. Las que están muy por debajo del visor del dispositivo sólo se recuperan cuando el usuario se desplaza cerca de ellas.

La implementación de Chromium de carga lenta nativa trata de asegurar que las imágenes fuera de pantalla se carguen lo suficientemente temprano para que terminen de cargarse una vez que el usuario se acerque a ellas. Al buscar las imágenes cercanas antes de que se hagan visibles en el visor, maximizamos la posibilidad de que ya estén cargadas para cuando se hagan visibles.

Comparado con las bibliotecas de lazy-loading de JavaScript, los umbrales de búsqueda de imágenes que se desplazan a la vista pueden considerarse conservadores. El cromo está buscando una mejor alineación de estos umbrales con las expectativas de los desarrolladores.

Los experimentos realizados con Chrome en Android sugieren que en 4G, el 97,5% de las imágenes de debajo del pliegue que están cargadas con lazy-loading se cargaron completamente dentro de los 10ms de ser visibles. Incluso en las lentas redes 2G, el 92,6% de las imágenes por debajo del pliegue se cargaron completamente en 10ms. Esto significa que la carga lenta nativa ofrece una experiencia estable en cuanto a la visibilidad de los elementos que se desplazan a la vista.

El umbral de distancia no es fijo y varía en función de varios factores:

Puede encontrar los valores por defecto para los diferentes tipos de conexión efectiva en el Chromium source. Estos números, e incluso el enfoque de buscar sólo cuando se alcanza una cierta distancia del punto de vista, puede cambiar en un futuro próximo a medida que el equipo de Chrome mejore la heurística para determinar cuándo empezar a cargar.

En el Chrome 77+, puedes experimentar con estos diferentes umbrales simulando el network in DevTools. Mientras tanto, tendrá que anular el tipo de conexión efectiva del navegador utilizando el flag  chrome://flags/#force-effective-connection-type  

Mejora de los umbrales de ahorro de datos (data-savings) y de la distancia desde el punto de vista de la visión (distance-from-viewport)

A partir de julio de 2020, Chrome ha realizado mejoras significativas para alinear los umbrales de la distancia de carga de la imagen nativa con los umbrales de la vista para cumplir mejor con las expectativas de los desarrolladores.

En las conexiones rápidas (por ejemplo, 4G), redujimos los umbrales de distancia de Chrome de 3000px a 1250px y en las conexiones más lentas (por ejemplo, 3G), cambiamos el umbral de 4000px a 2500px. Este cambio logra dos cosas:

  • <img loading=lazy>  se comporta más cerca de la experiencia que ofrecen las bibliotecas de carga lenta de JavaScript.
  • Los nuevos umbrales de distancia de visión todavía nos permiten garantizar que las imágenes se han cargado probablemente en el momento en que el usuario se ha desplazado hasta ellas.

Puedes encontrar una comparación entre los antiguos y los nuevos umbrales de distancia de visión para una de nuestras demostraciones en una conexión rápida (4G) abajo:

Viejos umbrales. vs. nuevos umbrales:

y los nuevos umbrales vs. LazySizes (una popular biblioteca de carga lenta de JS):

Para asegurarnos de que los usuarios de Chrome en las versiones recientes también se beneficien de los nuevos umbrales, hemos respaldado estos cambios para que Chrome 79 - 85 inclusive también los utilice. Por favor, tenga esto en cuenta si intenta comparar los ahorros de datos de las versiones antiguas de Chrome con las más recientes.

Los desarrolladores de Google se han comprometido a trabajar con la comunidad de estándares web para explorar una mejor alineación en la forma en que se abordan los umbrales de distancia a la vista en los diferentes navegadores.

Las imágenes deben incluir atributos de dimensión 

Mientras el navegador carga una imagen, no conoce inmediatamente las dimensiones de la misma, a menos que éstas se especifiquen explícitamente. Para que el navegador pueda reservar suficiente espacio en una página para las imágenes, se recomienda que todas las etiquetas <img> incluyan atributos de anchura y altura. Sin dimensiones especificadas, cambios de disposición que son más notables en las páginas que tardan en cargarse.

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

Alternativamente, especifique sus valores directamente en un estilo en línea:

<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">

La mejor práctica para establecer las dimensiones se aplica a las etiquetas <img> independientemente de si se están cargando en diferido o no. Con el lazy-load, esto puede ser más relevante. Establecer el ancho y la altura de las imágenes en los navegadores modernos también permite a los navegadores inferir su tamaño intrínseco.

Las imágenes seguirán cargándose con lazy-load si no se incluyen las dimensiones, pero si se especifican disminuye la posibilidad de que se desplacen. Si no se pueden incluir dimensiones para las imágenes, el lazy-loading de ellas puede ser una compensación entre el ahorro de recursos de red y el riesgo potencial de un cambio de diseño.

Si bien el lazy-loading nativo en el Cromium se implementa de tal manera que es probable que las imágenes se carguen una vez que son visibles, todavía hay una pequeña posibilidad de que no se carguen todavía. En este caso, la falta de atributos de anchura y altura en tales imágenes aumenta su impacto en el desplazamiento acumulado de la disposición.

Mira a esta demo para ver cómo funciona el atributo de carga con 100 imágenes.

Las imágenes que se definen usando el elelento <picture> pueden ser tambien puestas con lazy-load:

<picture>
<source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
<img src="photo.jpg" loading="lazy">
</picture>

Aunque un navegador decidirá qué imagen cargar de cualquiera de los elementos <source>, el atributo de carga sólo tiene que ser incluido en el elemento <img> de reserva.

Evita las imágenes de lazy-loading que se encuentran en el primer punto de vista visible 

Deberías evitar poner loading=lazy para cualquier imagen que esté en la primera vista visible.

Se recomienda añadir sólo loading=lazy a las imágenes que están posicionadas debajo del pliegue, si es posible. Las imágenes que se cargan con prioridad se pueden recuperar de inmediato, mientras que con las imágenes que se cargan con lazy-loading el navegador debe esperar hasta que sepa dónde está posicionada la imagen en la página, lo que depende de que el IntersectionObserver esté disponible.

En el Chromium, el impacto de las imágenes en el visor inicial marcado con loading=lazy en LargestContentfulPaint es bastante pequeño, con una regresión de <1% en los percentiles 75 y 99 en comparación con las imágenes cargadas con entusiasmo.

Por lo general, cualquier imagen dentro del puerto de visualización debe ser cargada con anticipación usando los valores predeterminados del navegador. No es necesario especificar load=eager para que esto sea así en las imágenes del visor.

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

La compatibilidad de degradación

Los navegadores que aún no soportan el atributo de carga ignorarán su presencia. Aunque estos navegadores no obtendrán, por supuesto, los beneficios del lazy-loading, incluir el atributo no tiene ningún impacto negativo en ellos.

FAQ 

¿Hay planes para aplicar el lazy load automáticamente a las imágenes en Chrome? 

Chromium ya carga automáticamente las imágenes que son adecuadas para ser aplazadas si el modo Lite está habilitado en Chrome para Android. Esto está dirigido principalmente a los usuarios que son conscientes de los ahorros de datos.  

¿Puedo cambiar la distancia que debe estar una imagen antes de que se dispare una carga? 

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

¿Pueden las imágenes de fondo CSS aprovechar el atributo de carga? 

No, actualmente sólo puede ser usado con etiquetas <img>.

¿Hay algún inconveniente en que las imágenes de carga lenta estén dentro del puerto de visualización del dispositivo? 

Es más seguro evitar poner "loading=lazy" en las imágenes por encima del pliegue, ya que Chrome no precargará las imágenes "loading=lazy" en el escáner de precarga.

¿Cómo funciona el atributo de carga con imágenes que están en la ventana de visualización pero que no son visibles inmediatamente (por ejemplo: detrás de un carrusel, o escondidas por CSS para ciertos tamaños de pantalla)? 

Sólo las imágenes que están por debajo de la vista del dispositivo por la distancia calculada se cargan con el lazy-loading. Todas las imágenes por encima del visor, independientemente de si son inmediatamente visibles, se cargan normalmente.

¿Y si ya estoy usando una biblioteca de terceros o un script para cargar imágenes con lazy-load? 

El atributo de carga no debería afectar de ninguna manera al código que actualmente carga con lazy-load sus activos, pero hay algunas cosas importantes a considerar:

  1. Si su cargador lazy personalizado intenta cargar imágenes o cuadros antes de que Chrome los cargue normalmente, es decir, a una distancia mayor que el umbral de distancia de carga— todavía se aplazan y se cargan en función del comportamiento normal del navegador.
  2. Si su lazy-loader personalizado utiliza una distancia más corta para determinar cuándo cargar una imagen en particular que el navegador, entonces el comportamiento se ajustará a su configuración personalizada.

Una de las razones importantes para seguir utilizando una biblioteca de terceros junto con loading="lazy" es proporcionar un polyfill para los navegadores que todavía no soportan el atributo.

¿Cómo manejo los navegadores que aún no soportan la carga nativa en lazy-loading? 

Cree un polyfill o utilice una biblioteca de terceros para cargar imágenes en su sitio. La propiedad de carga puede ser usada para detectar si la característica es soportada en el navegador:

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

Por ejemplo, lazysizes es una popular biblioteca de carga lazy-loading de JavaScript. Puede detectar el soporte del atributo loading para cargar lazysizes como una biblioteca de reserva sólo cuando la carga no está soportada. Esto funciona de la siguiente manera:

  • Reemplace <img src> por <img data-src> para evitar una carga ansiosa en los navegadores no soportados.Si el atributo loading está soportado, intercambie datos-src por src.
  • Si la carga no es soportada, cargue una reserva (lazysizes) e iníciela. Según los documentos de lazysizes, se utiliza la clase lazyload como una forma de indicar a los lazysizes qué imágenes deben cargarse.
<!-- 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>

Aquí hay una demo de este patrón. Pruébalo en un navegador como Firefox o Safari para ver el retroceso en acción.

La biblioteca de lazysizes también proporciona un plugin de carga nativa que utiliza lazy-loading nativo cuando está disponible, pero recurre a la funcionalidad personalizada de la biblioteca cuando es necesario.

¿La carga lazy-load de los iframes también está soportada en Chrome? 

<iframe loading=lazy>  fue recientemente estandarizado y ya se aplica en el Chromium. Esto permite cargar con lazy-load a los iframes usando el atributo de carga.

El atributo de carga afecta a los iframes de forma diferente a las imágenes, dependiendo de si el iframe está oculto. (Los iframes ocultos suelen utilizarse con fines analíticos o de comunicación). Chrome utiliza los siguientes criterios para determinar si un iframe está oculto:

  • El ancho y la altura del iframe son de 4 px o menos.
  • display: none o visibility: hidden es aplicado.
  • The iframe is placed off-screen using negative X or Y positioning.

Si un iframe cumple alguna de estas condiciones, Chrome lo considera oculto y no lo cargará perezosamente en la mayoría de los casos. Los iframes que no están ocultos sólo se cargarán cuando estén dentro del umbral de distancia de carga. Un marcador de posición muestra los iframes cargados con lazy-load que aún están siendo buscados.

¿Cómo afecta el lazy-loading nativo a los anuncios en una página web? 

Todos los anuncios que se muestran al usuario en forma de imagen o iframe se cargan en lazy-load como cualquier otra imagen o iframe.

¿Cómo se manejan las imágenes cuando se imprime una página web? 

Aunque la funcionalidad no está en Chrome actualmente, hay una incidencia abierta para asegurar que todas las imágenes y iframes se cargan inmediatamente si se imprime una página.

¿Reconocerá Lighthouse lel lazy-loading nativo? 

Las versiones anteriores de Lighthouse aún destacaban que las páginas que usaban loading=lazy on images requerían una estrategia para cargar imágenes fuera de la pantalla. Lighthouse 6.0 y superiores son un mejor factor en los enfoques para la carga perezosa de imágenes diferidas fuera de pantalla que pueden utilizar diferentes umbrales, permitiéndoles pasar la auditoría de imágenes diferidas fuera de pantalla.

Conclusión 

El soporte nativo para imágenes en lazy-loading puede facilitarle considerablemente la mejora del rendimiento de sus páginas web.

original article: https://web.dev/native-lazy-loading/

 
by Luigi Nori Date: 04-08-2020 lazy loading chrome nativo visitas : 1073  
 
Luigi Nori

Luigi Nori

He has been working on the Internet since 1994 (practically a mummy), specializing in Web technologies makes his customers happy by juggling large scale and high availability applications, php and js frameworks, web design, data exchange, security, e-commerce, database and server administration, ethical hacking. He happily lives with @salvietta150x40, in his (little) free time he tries to tame a little wild dwarf with a passion for stars.

 
 
 

Artículos relacionados