Las imágenes y los elementos <iframe>
suelen consumir más ancho de banda que otros tipos de recursos. En el caso de los elementos <iframe>
, se puede requerir una gran cantidad de tiempo de procesamiento adicional para cargar y renderizar las páginas que contienen.
En el caso de las imágenes de carga diferida, aplazar la carga de imágenes que están fuera del viewport inicial puede ser útil para reducir la contención de ancho de banda para recursos más críticos dentro del viewport inicial. Esto puede mejorar el procesamiento de imagen con contenido más grande (LCP) de una página en algunos casos en los que las conexiones de red son deficientes, y ese ancho de banda reasignado puede ayudar a que los candidatos de LCP se carguen y pinten más rápido.
En el caso de los elementos <iframe>
, se puede mejorar la Interaction to Next Paint (INP) de una página durante el inicio cargándolos de forma diferida. Esto se debe a que un <iframe>
es un documento HTML completamente independiente con sus propios subrecursos.
Si bien los elementos <iframe>
se pueden ejecutar en un proceso independiente, no es raro
que compartan un proceso con otros subprocesos, lo que puede crear condiciones
en las que las páginas se vuelven menos responsivas a las entradas del usuario.
Por lo tanto, aplazar la carga de imágenes fuera de la pantalla y elementos <iframe>
es una técnica que vale la pena seguir y requiere un esfuerzo bastante bajo para obtener un rendimiento bastante bueno. En este módulo, se explica cómo cargar de forma diferida estos dos tipos de elementos para obtener una experiencia del usuario más rápida y mejor durante el período de inicio crítico de la página.
Carga imágenes de forma diferida con el atributo loading
El atributo loading
se puede agregar a los elementos <img>
para indicarles a los navegadores cómo deben cargarse:
"eager"
le informa al navegador que la imagen se debe cargar de inmediato, incluso si está fuera del viewport inicial. Este también es el valor predeterminado del atributoloading
."lazy"
aplaza la carga de una imagen hasta que esté dentro de una distancia establecida del viewport visible. Esta distancia varía según el navegador, pero a menudo se establece para que sea lo suficientemente grande como para que la imagen se cargue cuando el usuario se desplaza hasta ella.
También vale la pena señalar que, si usas el elemento <picture>
, el atributo loading
se debe aplicar a su elemento secundario <img>
, no al elemento <picture>
en sí. Esto se debe a que el elemento <picture>
es un contenedor que contiene elementos <source>
adicionales que apuntan a diferentes candidatos de imagen, y el candidato que elige el navegador se aplica directamente a su elemento <img>
secundario.
No cargues de forma diferida las imágenes que se encuentran en el viewport inicial.
Solo debes agregar el atributo loading="lazy"
a los elementos <img>
que se encuentran fuera del viewport inicial. Sin embargo, puede ser complejo conocer la posición precisa de un elemento en relación con el viewport antes de que se renderice la página. Se deben tener en cuenta diferentes tamaños de viewport, relaciones de aspecto y dispositivos.
Por ejemplo, el viewport de una computadora de escritorio puede ser muy diferente al de un teléfono celular, ya que renderiza más espacio vertical, lo que puede permitir que se ajusten imágenes en el viewport inicial que no aparecerían en el viewport inicial de un dispositivo físicamente más pequeño. Las tablets que se usan en orientación vertical también muestran una cantidad considerable de espacio vertical, quizás incluso más que algunos dispositivos de escritorio.
Sin embargo, hay algunos casos en los que es bastante claro que debes evitar aplicar loading="lazy"
. Por ejemplo, debes omitir el atributo loading="lazy"
de los elementos <img>
en el caso de las imágenes hero o en otros casos de uso de imágenes en los que es probable que los elementos <img>
aparezcan sobre el pliegue o cerca de la parte superior del diseño en cualquier dispositivo. Esto es aún más importante para las imágenes que pueden ser candidatas a LCP.
Las imágenes que se cargan de forma diferida deben esperar a que el navegador finalice el diseño para saber si la posición final de la imagen está dentro del viewport. Esto significa que, si un elemento <img>
en el viewport visible tiene un atributo loading="lazy"
, solo se solicita después de que se descargue, analice y aplique todo el CSS a la página, en lugar de recuperarlo en cuanto lo descubra el escáner de carga previa en el marcado sin procesar.
Dado que el atributo loading
en el elemento <img>
es compatible con todos los navegadores principales, no es necesario usar JavaScript para cargar imágenes de forma diferida, ya que agregar JavaScript adicional a una página para proporcionar capacidades que el navegador ya proporciona afecta otros aspectos del rendimiento de la página, como la INP.
Demostración de la carga diferida de imágenes
Carga diferida de elementos <iframe>
La carga diferida de elementos <iframe>
hasta que sean visibles en el viewport puede ahorrar datos significativos y mejorar la carga de recursos críticos que se requieren para que se cargue la página de nivel superior. Además, como los elementos <iframe>
son, en esencia, documentos HTML completos cargados dentro de un documento de nivel superior, pueden incluir una cantidad significativa de subrecursos, en particular JavaScript, que puede afectar considerablemente el INP de una página si las tareas dentro de esos marcos requieren un tiempo de procesamiento significativo.
Las incorporaciones de terceros son un caso de uso común para los elementos <iframe>
. Por ejemplo, los reproductores de video incorporados o las publicaciones de redes sociales suelen usar elementos <iframe>
y, a menudo, requieren una cantidad significativa de subrecursos, lo que también puede generar una contención de ancho de banda para los recursos de la página de nivel superior. Por ejemplo, la carga diferida de la incorporación de un video de YouTube ahorra más de 500 KiB durante la carga inicial de la página, mientras que la carga diferida del complemento del botón de Me gusta de Facebook ahorra más de 200 KiB, la mayoría de los cuales es JavaScript.
De cualquier manera, cada vez que tengas un <iframe>
debajo de la mitad inferior de una página, debes considerar la carga diferida si no es fundamental cargarlo de antemano, ya que hacerlo puede mejorar significativamente la experiencia del usuario.
El atributo loading
para los elementos <iframe>
El atributo loading
en los elementos <iframe>
también se admite en todos los navegadores principales. Los valores del atributo loading
y sus comportamientos son los mismos que los de los elementos <img>
que usan el atributo loading
:
"eager"
es el valor predeterminado. Le informa al navegador que cargue el HTML del elemento<iframe>
y sus subrecursos de inmediato."lazy"
aplaza la carga del código HTML del elemento<iframe>
y sus subrecursos hasta que se encuentre dentro de una distancia predefinida del viewport.
Demostración de iframes de carga diferida
Fachadas
En lugar de cargar una incorporación inmediatamente durante la carga de la página, puedes cargarla a pedido en respuesta a una interacción del usuario. Para ello, puedes mostrar una imagen o cualquier otro elemento HTML adecuado hasta que el usuario interactúe con él. Una vez que el usuario interactúa con el elemento, puedes reemplazarlo por la incorporación de terceros. Esta técnica se conoce como fachada.
Un caso de uso común para las fachadas son las incorporaciones de videos de servicios de terceros, en las que la incorporación puede implicar la carga de muchos subrecursos adicionales y potencialmente costosos, como JavaScript, además del contenido del video en sí. En ese caso, a menos que haya una necesidad legítima de que un video se reproduzca automáticamente, las incorporaciones de video requieren que el usuario haga clic en el botón de reproducción para interactuar con ellas antes de la reproducción.
Esta es una excelente oportunidad para mostrar una imagen estática que sea visualmente similar a la incorporación del video y ahorrar un ancho de banda significativo en el proceso. Una vez que el usuario hace clic en la imagen, esta se reemplaza por la incorporación real de <iframe>
, que activa el HTML del elemento <iframe>
de terceros y sus subrecursos para que comiencen a descargarse.
Además de mejorar la carga inicial de la página, otro beneficio clave es que, si el usuario nunca reproduce el video, los recursos necesarios para entregarlo nunca se descargan. Este es un buen patrón, ya que garantiza que el usuario solo descargue lo que realmente quiere, sin hacer suposiciones posiblemente erróneas sobre sus necesidades.
Los widgets de chat son otro excelente caso de uso para la técnica de fachada. La mayoría de los widgets de chat descargan cantidades significativas de JavaScript que pueden afectar de forma negativa la carga de la página y la capacidad de respuesta a las entradas del usuario. Al igual que con la carga de cualquier elemento por adelantado, el costo se genera en el tiempo de carga, pero en el caso de un widget de chat, no todos los usuarios tienen la intención de interactuar con él.
Por otro lado, con una fachada, es posible reemplazar el botón "Iniciar chat" de terceros por un botón falso. Una vez que el usuario interactúa con él de manera significativa, por ejemplo, mantiene un puntero sobre él durante un período razonable o hace clic, el widget de chat funcional real se coloca en su lugar cuando el usuario lo necesita.
Si bien es posible crear tus propias fachadas, existen opciones de código abierto disponibles para terceros más populares, como lite-youtube-embed
para videos de YouTube, lite-vimeo-embed
para videos de Vimeo y React Live Chat Loader para widgets de chat.
Bibliotecas de carga diferida de JavaScript
Si necesitas cargar de forma diferida elementos <video>
, imágenes poster
de elementos <video>
, imágenes cargadas por la propiedad background-image
de CSS o otros elementos no compatibles, puedes hacerlo con una solución de carga diferida basada en JavaScript, como lazysizes o yall.js, ya que la carga diferida de estos tipos de recursos no es una función a nivel del navegador.
En particular, la reproducción automática y el bucle de elementos <video>
sin una pista de audio son una alternativa mucho más eficiente que usar GIFs animados, que a menudo pueden ser varias veces más grandes que un recurso de video de calidad visual equivalente. Aun así, estos videos pueden ser significativos en términos de ancho de banda, por lo que la carga diferida es una optimización adicional que puede ayudar mucho a reducir el ancho de banda desperdiciado.
La mayoría de estas bibliotecas funcionan con la API de Intersection Observer y, además, con la API de Mutation Observer si el HTML de una página cambia después de la carga inicial para reconocer cuándo un elemento ingresa al viewport del usuario. Si la imagen es visible o se acerca al viewport, la biblioteca de JavaScript reemplaza el atributo no estándar (a menudo, data-src
o un atributo similar) por el atributo correcto, como src
.
Supongamos que tienes un video que reemplaza un GIF animado, pero quieres cargarlo de forma diferida con una solución de JavaScript. Esto es posible con yall.js con el siguiente patrón de marcado:
<!-- The autoplay, loop, muted, and playsinline attributes are to
ensure the video can autoplay without user intervention. -->
<video class="lazy" autoplay loop muted playsinline width="320" height="480">
<source data-src="video.webm" type="video/webm">
<source data-src="video.mp4" type="video/mp4">
</video>
De forma predeterminada, yall.js observa todos los elementos HTML que califican con una clase de "lazy"
. Una vez que se carga y ejecuta yall.js en la página, el video no se carga hasta que el usuario lo desplaza hasta el viewport. En ese momento, los atributos data-src
de los elementos <source>
secundarios del elemento <video>
se cambian a atributos src
, que envían una solicitud para descargar el video y comenzar a reproducirlo automáticamente.
Ponga a prueba sus conocimientos
¿Cuál es el valor predeterminado del atributo loading
para los elementos <img>
y <iframe>
?
"eager"
"lazy"
¿Cuándo es razonable usar soluciones de carga diferida basadas en JavaScript?
loading
, como en el caso de los videos con reproducción automática destinados a reemplazar imágenes animadas o para cargar de forma diferida la imagen de póster de un elemento <video>
.
¿Cuándo es útil una fachada?
A continuación: Carga previa y renderización previa
Ahora que tienes el control de las imágenes de carga diferida y los elementos <iframe>
,
estás en una buena posición para asegurarte de que las páginas se carguen más rápido y, al mismo tiempo,
respetar las necesidades de tus usuarios. Sin embargo, hay casos en los que puede ser conveniente la carga especulativa de recursos. En el siguiente módulo, aprenderás sobre la carga previa y la renderización previa, y cómo estas técnicas, cuando se usan con cuidado, pueden acelerar significativamente las navegaciones a páginas posteriores cargándolas con anticipación.