Carga diferida híbrida: una migración progresiva a la carga diferida nativa
Publicado: 2022-03-10En las últimas semanas, es posible que haya escuchado o leído acerca de la carga diferida nativa, que llegará a Chromium 75 en los próximos meses.
"Sí, buenas noticias, pero tendremos que esperar hasta que todos los navegadores lo admitan".
Si esto fue lo primero que se te pasó por la cabeza, sigue leyendo. Intentaré convencerte de lo contrario.
Comencemos con una comparación entre la carga diferida nativa y la buena y antigua impulsada por JavaScript.
Carga perezosa nativa frente a JavaScript
La carga diferida es una forma de mejorar el rendimiento de un sitio web o una aplicación web maximizando la velocidad de representación de las imágenes e iframes de la mitad superior de la página (y, a veces, de los videos) al diferir la carga del contenido de la mitad inferior de la página.
Carga diferida impulsada por JavaScript
Para cargar imágenes o iframes de forma diferida, es una práctica muy común marcarlos reemplazando el atributo src
adecuado con un atributo de datos similar, data-src
, y luego confiar en una solución de JavaScript para detectar cuándo las imágenes/iframes están recibiendo cerca de la parte visible del sitio web (por lo general, porque el usuario se desplazó hacia abajo) y para copiar los atributos de datos en los adecuados, lo que luego activa la carga diferida de su contenido.
<img data-src="turtle.jpg" alt="Lazy turtle" class="lazy">
Carga diferida nativa
De acuerdo con la especificación de carga diferida nativa (todavía en desarrollo), si desea cargar imágenes o iframes de forma diferida utilizando la función de carga diferida nativa, solo necesita agregar el atributo loading=lazy
en la etiqueta relacionada.
<img src="turtle.jpg" alt="Lazy turtle" loading="lazy">
Addy Osmani escribió extensamente sobre este tema en su artículo “Native Image Lazy-Loading For The Web!” en el que afirmó que el equipo de Google Chrome ya está desarrollando la función y tiene la intención de enviarla en Chrome 75.
Otros navegadores basados en Chromium como Opera y Microsoft Edge también se beneficiarán de este desarrollo al obtener la misma función en su primera actualización basada en Chromium 75.
Comience con la carga diferida nativa
En caso de que las imágenes de su sitio web se descarguen todas a la vez en la página de aterrizaje sin carga diferida, puede habilitar (cuando sea compatible) la carga diferida nativa en su sitio web tan fácilmente como agregar un atributo HTML. El atributo loading
le dice a los navegadores qué imágenes son importantes para cargar de inmediato y cuáles se pueden descargar lentamente a medida que los usuarios se desplazan hacia abajo. El mismo atributo se puede aplicar a iframes.
Para decirles a los navegadores que una imagen en particular es importante para que puedan cargarla lo antes posible, debe agregar el atributo loading="eager"
en la etiqueta img
. La mejor práctica es hacer esto para las imágenes principales, generalmente para las que se mostrarán en la parte superior de la página.
<img src="rabbit.jpg" alt="Fast rabbit" loading="eager">
Para decirle a los navegadores que una imagen debe descargarse de forma diferida, simplemente agregue el atributo loading="lazy"
. Esta es una mejor práctica solo si lo hace solo con imágenes secundarias, generalmente para las que se mostrarán debajo del pliegue.
<img src="turtle.jpg" alt="Lazy turtle" loading="lazy">
Con solo agregar el atributo de loading
a sus imágenes e iframes, permitirá que su sitio web use la carga diferida nativa como una mejora progresiva. Su sitio web se beneficiará gradualmente a medida que el soporte llegue a sus usuarios en la mayoría de los navegadores modernos.
Este es el mejor enfoque para usar si su sitio web no usa ningún tipo de carga diferida hoy en día, pero si ya implementó una solución de carga diferida basada en JavaScript, es posible que desee conservarla mientras cambia progresivamente a la carga diferida nativa.
La solución ideal sería comenzar a usar la carga diferida nativa de inmediato y usar un polyfill para que funcione en todos los navegadores. Desafortunadamente, la carga diferida nativa no es una característica que podamos polillenar con JavaScript.
No sirve para un Polyfill
Cuando se lanza una nueva tecnología de navegador a un solo navegador, la comunidad de código abierto generalmente lanza un polyfill de JavaScript para proporcionar la misma tecnología al resto de los navegadores. Por ejemplo, el polyfill IntersectionObserver
usa elementos JavaScript y DOM para coordinar Element.getBoundingClientRect()
para reproducir el comportamiento de la API nativa.
Pero el caso de la carga diferida nativa es diferente porque un polyfill de JavaScript para loading="lazy"
tendría que evitar que los navegadores carguen contenido tan pronto como encuentren una URL en el marcado de una imagen o iframe. JavaScript no tiene control sobre esta etapa inicial de la representación de la página, por lo tanto, no es posible realizar un polyfill de carga diferida nativa.
Carga diferida híbrida
Si no está satisfecho con tener la carga diferida nativa solo como una mejora progresiva, o si ya ha implementado la carga diferida basada en JavaScript y no desea perder esta función en navegadores menos modernos (pero aún desea habilitar la carga diferida nativa en navegadores que lo admiten), entonces necesita una solución diferente. Presentamos: carga diferida híbrida.
La carga diferida híbrida es una técnica para usar la carga diferida nativa en los navegadores que la admiten; de lo contrario, confíe en JavaScript para manejar la carga diferida.
“
Para realizar la carga diferida híbrida, debe marcar su contenido diferido utilizando los atributos de data
en lugar de los reales (como en la carga diferida basada en JavaScript) y agregar el atributo loading="lazy"
.
<img data-src="turtle.jpg" loading="lazy" alt="Lazy turtle">
Entonces necesitas algo de JavaScript. En primer lugar, debe detectar si el navegador admite o no la carga diferida nativa . Luego, realiza una de las siguientes acciones para cada elemento con el atributo loading="lazy"
:
- Si se admite la carga diferida nativa, copie el valor del atributo
data-src
en el atributosrc
; - Si no es compatible, inicialice un script o complemento de carga diferida de JavaScript para hacerlo cuando los elementos ingresen a la ventana gráfica.
No es muy difícil escribir el código JavaScript necesario para realizar estas operaciones por su cuenta. Puede detectar si la carga diferida nativa es compatible con la condición:
if ('loading' in HTMLImageElement.prototype)
Si es así, simplemente copie el valor del atributo src
de data-src
. Si no es así, inicialice algún script de carga diferida de su elección.
Aquí hay un fragmento de código que hace eso.
<!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <script> (function() { if ("loading" in HTMLImageElement.prototype) { var lazyEls = document.querySelectorAll("[loading=lazy]"); lazyEls.forEach(function(lazyEl) { lazyEl.setAttribute( "src", lazyEl.getAttribute("data-src") ); }); } else { // Dynamically include a lazy loading library of your choice // Here including vanilla-lazyload var script = document.createElement("script"); script.async = true; script.src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"; window.lazyLoadOptions = { elements_selector: "[loading=lazy]" //eventually more options here }; document.body.appendChild(script); } })(); </script>
Puede encontrar y probar el código anterior en esta demostración en vivo.
Aún así, ese es un script muy básico, y las cosas pueden complicarse cuando usa atributos o etiquetas adicionales para obtener imágenes receptivas (como los atributos srcset
y sizes
o incluso las etiquetas de picture
y source
).
Un poco de ayuda de terceros
Durante los últimos cuatro años, he mantenido un script de carga diferida de código abierto llamado " vanilla-lazyload
" y, un par de días después de que Addy Osmani escribiera sobre la carga diferida nativa, la comunidad reaccionó preguntándome si mi script podría actuar como un polirelleno.
Como expliqué antes, no puede crear un polyfill para la función de carga diferida nativa, sin embargo, pensé en una solución que facilitaría a los desarrolladores comenzar la transición a la carga diferida nativa, sin necesidad de escribir nada del código JavaScript que he mencionado antes.
A partir de la versión 12 de vanilla-lazyload
, puede establecer la opción use_native
en true
para habilitar la carga híbrida diferida. El script tiene solo 2,0 kB comprimidos con gzip y ya está disponible en GitHub, npm y jsDelivr.
- Conozca
vanilla-lazyload
en GitHub
Población
Puede comenzar a jugar con la carga diferida nativa hoy mismo descargando Chrome Canary o Microsoft Edge Insider ( canal de desarrollo ) y luego habilitando las banderas "Habilitar carga diferida de imágenes" y "Habilitar carga diferida de marcos". Para habilitar estas banderas, ingrese about:flags
en el campo URL de su navegador y busque "perezoso" en el cuadro de búsqueda.
Demostración de carga diferida nativa
Para analizar cómo funciona la carga diferida nativa en las herramientas de desarrollo, puede comenzar a jugar con la siguiente demostración. En este no se utiliza ni una sola línea de JavaScript . Sí, es simplemente carga diferida nativa completa.
- Pruebe la demostración de carga diferida nativa
Qué esperar : todas las imágenes se obtienen a la vez, pero con diferentes respuestas HTTP. Las que tienen el código de respuesta 200
son las imágenes cargadas con entusiasmo, mientras que las que tienen el código de respuesta 206
solo se recuperan parcialmente para obtener la información inicial sobre las imágenes. Esas imágenes se recuperarán por completo con un código de respuesta 200
cuando se desplace hacia abajo.
Demostración de carga diferida híbrida
Para analizar cómo funciona la carga diferida híbrida, puede comenzar a jugar con la siguiente demostración. Aquí, se usa [email protected]
y la opción use_native
se establece en true
:
- Pruebe la demostración de carga diferida híbrida
Qué esperar : pruebe la demostración en diferentes navegadores para ver cómo se comporta. En los navegadores que admiten la carga diferida nativa, el comportamiento sería el mismo que en la demostración de carga diferida nativa. En los navegadores que no admiten la carga diferida nativa, las imágenes se descargarán a medida que se desplaza hacia abajo.
Tenga en cuenta que vanilla-lazyload
utiliza la API de IntersectionObserver internamente, por lo que deberá completarlo en Internet Explorer y en versiones menos recientes de Safari. Sin embargo, no es gran cosa si no se proporciona un polyfill, porque en ese caso vanilla-lazyload
simplemente descargaría todas las imágenes a la vez.
Nota : Obtenga más información en el capítulo "Polyfill or Not To Polyfill" del archivo Léame de vanilla-lazyload
.
Pruebe Hybrid Lazy Loading en su sitio web
Dado que la carga diferida nativa llegará pronto a algunos navegadores, ¿por qué no le das una oportunidad hoy usando la carga diferida híbrida? Esto es lo que debe hacer:
Marcado HTML
El marcado de imagen más simple está hecho por dos atributos: src
y alt
.
Para las imágenes de la mitad superior de la página, debe dejar el atributo src
y agregar el atributo loading="eager"
.
<img src="important.jpg" loading="eager" alt="Important image">
Para las imágenes de la mitad inferior de la página, debe reemplazar el atributo src
con el atributo data-src
y agregar el atributo loading="lazy"
.
<img data-src="lazy.jpg" loading="lazy" alt="A lazy image">
Si desea utilizar imágenes receptivas, haga lo mismo con los atributos srcset
y sizes
.
<img alt="A lazy image" loading="lazy" data-src="lazy.jpg">
Si prefiere usar la etiqueta de la picture
, cambie el srcset
, los sizes
y el src
también en las etiquetas de source
.
<picture> <source media="(min-width: 1200px)"> <source media="(min-width: 800px)"> <img alt="A lazy image" loading="lazy" data-src="lazy.jpg"> </picture>
La etiqueta de picture
también se puede utilizar para cargar selectivamente el formato WebP para sus imágenes.
Nota : si desea conocer más usos de vanilla-lazyload
, lea la sección HTML "Primeros pasos" de su archivo Léame.
Código JavaScript
En primer lugar, debe incluir vanilla-lazyload
en su sitio web.
Puedes cargarlo desde un CDN como jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>
O puede instalarlo usando npm:
npm install vanilla-lazyload@12
También es posible usar un script async
con inicialización automática; cárguelo como un módulo ES usando type="module"
o cárguelo como AMD usando RequireJS. Encuentre más formas de incluir y usar vanilla-lazyload
en la sección de secuencias de comandos "Introducción" del archivo Léame.
Luego, en el código JavaScript de su sitio web/aplicación web, incluya lo siguiente:
var pageLazyLoad = new LazyLoad({ elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading });
Nota : el script tiene muchas otras configuraciones que puede usar para personalizar el comportamiento vanilla-lazyload
, por ejemplo, para aumentar la distancia del área de desplazamiento desde la cual comenzar a cargar los elementos o para cargar elementos solo si permanecieron en la ventana gráfica durante un tiempo dado. Encuentre más configuraciones en la sección API del archivo Léame.
Todos juntos, utilizando un script async
Para ponerlo todo junto y usar un script async
para maximizar el rendimiento, consulte el siguiente código HTML y JavaScript:
<!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <!-- Set the options for the global instance of vanilla-lazyload --> <script> window.lazyLoadOptions = { elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading }; </script> <!-- Include vanilla lazyload 12 through an async script --> <script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>
¡Eso es todo! ¡Con estos pasos muy simples y sencillos, habrá habilitado la carga diferida híbrida en su sitio web!
Prácticas recomendadas importantes
- Aplique la carga diferida solo a las imágenes que sabe que probablemente se mostrarán debajo del pliegue. Cargue con entusiasmo los que están arriba del pliegue para maximizar el rendimiento. Si solo aplica la carga diferida a todas las imágenes de su página, ralentizará el rendimiento de la representación.
- Utilice CSS para reservar algo de espacio para las imágenes antes de que se carguen. De esa manera, impulsarán el resto del contenido a continuación. Si no lo hace, se colocará una mayor cantidad de imágenes en la mitad superior de la página antes de lo que deberían, lo que desencadenará descargas inmediatas para ellas. Si necesita un truco de CSS para hacer eso, puede encontrar uno en la sección de trucos y consejos del archivo Léame de
vanilla-lazyload
.
Pros y contras
CARGA PEREZOSA NATIVA | |
---|---|
PROS |
|
CONTRAS |
|
CARGA PEREZOSA IMPULSADA POR JAVASCRIPT | |
---|---|
PROS |
|
CONTRAS |
|
CARGA PEREZOSA HÍBRIDA | |
---|---|
PROS |
|
CONTRAS |
|
Terminando
Estoy muy emocionado de que la carga diferida nativa llegue a los navegadores, ¡y no puedo esperar a que todos los proveedores de navegadores la implementen!
Mientras tanto, puede optar por enriquecer su marcado HTML para una mejora progresiva y obtener la carga diferida nativa solo donde sea compatible, o puede optar por la carga diferida híbrida y obtener la carga diferida nativa y basada en JavaScript hasta el día en que la carga diferida nativa lo haga. ser compatible con la gran mayoría de los navegadores.
¡Darle una oportunidad! No te olvides de protagonizar/ver vanilla-lazyload
en GitHub y déjame saber tu opinión en la sección de comentarios.
Lectura adicional en SmashingMag:
- Now You See Me: cómo diferir, cargar de forma diferida y actuar con IntersectionObserver
- Lazy Loading Módulos de JavaScript con ConditionerJS
- Lista de verificación de rendimiento de front-end 2019 (PDF, Apple Pages, MS Word)
- Cómo mejorar el rendimiento del sitio web puede ayudar a salvar el planeta