Cómo ayudar al navegador con las sugerencias de recursos

En el último módulo sobre cómo optimizar la carga de recursos, aprendiste cómo varios recursos de la página, como CSS y JavaScript, pueden afectar la velocidad de carga de la página, y cómo optimizarlos y su publicación para acelerar la renderización de una página. Este es el momento perfecto para pasar a un aspecto más avanzado de la carga de recursos, que implica ayudar al navegador a cargarlos más rápido mediante el uso de sugerencias de recursos.

Las sugerencias de recursos pueden ayudar a los desarrolladores a optimizar el tiempo de carga de las páginas, ya que informan al navegador sobre cómo cargar y priorizar los recursos. Un conjunto inicial de sugerencias de recursos, como preconnect y dns-prefetch, fueron las primeras en incorporarse. Sin embargo, con el tiempo, se siguieron preload y la API de Fetch Priority para proporcionar capacidades adicionales.

Las sugerencias de recursos le indican al navegador que realice ciertas acciones con anticipación que podrían mejorar el rendimiento de carga. Las sugerencias de recursos pueden realizar acciones como realizar búsquedas anticipadas de DNS, conectarse a servidores con anticipación o incluso recuperar recursos antes de que el navegador los encuentre.

Las sugerencias de recursos se pueden especificar en HTML, con mayor frecuencia al principio del elemento <head>, o configurarse como un encabezado HTTP. Para el alcance de este módulo, se abordan preconnect, dns-prefetch y preload, así como los comportamientos de recuperación especulativa que proporciona prefetch.

preconnect

La sugerencia preconnect se usa para establecer una conexión con otro origen desde el que recuperas recursos críticos. Por ejemplo, es posible que alojes tus imágenes o elementos en una CDN o en otro origen cruzado:

<link rel="preconnect" href="https://example.com">

Si usas preconnect, anticipas que el navegador planea conectarse a un servidor de origen cruzado específico en un futuro muy cercano y que el navegador debería abrir esa conexión lo antes posible, idealmente antes de esperar a que lo hagan el analizador de HTML o el escáner de precarga.

Si tienes una gran cantidad de recursos de origen cruzado en una página, usa preconnect para los recursos más importantes de la página actual.

Captura de pantalla de los tiempos de conexión de un recurso en el panel de red de las Herramientas para desarrolladores de Chrome. La configuración de la conexión incluye tiempo de inactividad, negociación de proxy, búsqueda de DNS, configuración de conexión y negociación de TLS.
Una visualización de los tiempos de conexión como se muestra en el panel de red de las Herramientas para desarrolladores de Chrome. Los tiempos dentro del cuadro rojo son los que se necesitan para configurar una conexión con un servidor de origen cruzado, que preconnect puede mitigar estableciendo las conexiones antes, en lugar de cuando se descubre el recurso de origen cruzado.

Un caso de uso común para preconnect es Google Fonts. Google Fonts recomienda usar preconnect en el dominio https://fonts.googleapis.com que entrega las declaraciones @font-face y en el dominio https://fonts.gstatic.com que entrega los archivos de fuente.

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

El atributo crossorigin se usa para indicar si un recurso se debe recuperar mediante el uso compartido de recursos entre dominios (CORS). Cuando se usa la sugerencia preconnect, si el recurso que se descarga del origen usa CORS, como los archivos de fuentes, debes agregar el atributo crossorigin a la sugerencia preconnect.

dns-prefetch

Si bien abrir las conexiones a servidores de origen cruzado antes de tiempo puede mejorar significativamente el tiempo de carga de la página inicial, es posible que no sea razonable o posible establecer conexiones a muchos servidores de origen cruzado a la vez. Si te preocupa que uses preconnect en exceso, la sugerencia de recursos mucho menos costosa es la sugerencia dns-prefetch.

Según su nombre, dns-prefetch no establece una conexión con un servidor de origen cruzado, sino que solo realiza la búsqueda de DNS por adelantado. Una búsqueda de DNS se produce cuando un nombre de dominio se resuelve en su dirección IP subyacente. Si bien las capas de caché DNS a nivel del dispositivo y de la red ayudan a que este proceso sea generalmente rápido, este proceso toma cierto tiempo.

<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://fonts.gstatic.com">

Las búsquedas de DNS son bastante económicas y, debido a su costo relativamente pequeño, pueden ser una herramienta más adecuada en algunos casos que un preconnect. En particular, puede ser una sugerencia de recurso conveniente para usar en casos de vínculos que navegan a otros sitios web que crees que el usuario podría seguir. dnstradamus es una herramienta que lo hace automáticamente con JavaScript y usa la API de Intersection Observer para insertar sugerencias de dns-prefetch en el código HTML de la página actual cuando los vínculos a otros sitios web se desplazan hacia el viewport del usuario.

preload

La directiva preload se usa para iniciar una solicitud anticipada de un recurso necesario para renderizar la página:

<link rel="preload" href="/lcp-image.jpg" as="image">

Las directivas preload deben limitarse a recursos críticos detectados de forma tardía. Los casos de uso más comunes son los archivos de fuentes, los archivos CSS que se recuperan mediante declaraciones @import o los recursos background-image de CSS que probablemente sean los candidatos de Largest Contentful Paint (LCP). En esos casos, el escáner de precarga no descubriría estos archivos, ya que se hace referencia al recurso en recursos externos.

Al igual que con preconnect, la directiva preload requiere el atributo crossorigin si precargas un recurso de CORS, como fuentes. Si no agregas el atributo crossorigin (o lo agregas para solicitudes que no son de CORS), el navegador descargará el recurso dos veces, lo que desperdicia el ancho de banda que se podría haber gastado mejor en otros recursos.

<link rel="preload" href="/font.woff2" as="font" crossorigin>

En el fragmento HTML anterior, se le indica al navegador que precarga /font.woff2 con una solicitud de CORS, incluso si /font.woff2 está en el mismo dominio.

prefetch

La directiva prefetch se usa para iniciar una solicitud de prioridad baja de un recurso que se pueda usar en navegaciones futuras:

<link rel="prefetch" href="/next-page.css" as="style">

Esta directiva sigue en gran medida el mismo formato que la directiva preload; solo el atributo rel del elemento <link> usa un valor de "prefetch" en su lugar. Sin embargo, a diferencia de la directiva preload, prefetch es bastante especulativa porque se inicia la recuperación de un recurso para una navegación futura que puede o no ocurrir.

A veces, prefetch puede ser beneficioso. Por ejemplo, si identificaste un flujo de usuarios en tu sitio web que la mayoría de los usuarios sigue hasta el final, un prefetch para un recurso fundamental de renderización para esas páginas futuras puede ayudar a reducir los tiempos de carga.

API de Fetch Priority

Puedes usar Fetch Priority API a través de su atributo fetchpriority para aumentar la prioridad de un recurso. Puedes usar el atributo con elementos <link>, <img> y <script>.

<div class="gallery">
  <div class="poster">
    <img src="img/poster-1.jpg" fetchpriority="high">
  </div>
  <div class="thumbnails">
    <img src="img/thumbnail-2.jpg" fetchpriority="low">
    <img src="img/thumbnail-3.jpg" fetchpriority="low">
    <img src="img/thumbnail-4.jpg" fetchpriority="low">
  </div>
</div>

De forma predeterminada, las imágenes se recuperan con una prioridad más baja. Después del diseño, si se descubre que la imagen está dentro del viewport inicial, la prioridad aumenta a Alta. En el fragmento HTML anterior, fetchpriority le indica inmediatamente al navegador que descargue la imagen LCP más grande con una prioridad Alta, mientras que las imágenes en miniatura menos importantes se descargan con una prioridad más baja.

Los navegadores modernos cargan recursos en dos fases. La primera fase se reserva para los recursos críticos y finaliza una vez que se descarguen y ejecuten todas las secuencias de comandos de bloqueo. Durante esta fase, es posible que la descarga de los recursos de prioridad Baja se retrase. Si usas fetchpriority="high", puedes aumentar la prioridad de un recurso y permitir que el navegador lo descargue durante la primera fase.

Demostraciones de sugerencias de recursos

Pon a prueba tus conocimientos

¿Qué hace la sugerencia del recurso preconnect?

Abre una conexión a un servidor de origen cruzado, que incluye la búsqueda de DNS, así como la conexión y la negociación de TLS antes de que el navegador la descubra.
Correcto.
Solo realiza una búsqueda de DNS para el servidor de origen cruzado.
Vuelve a intentarlo.

¿Qué te permite hacer la API de Fetch Priority?

Especifica la prioridad con la que se descarga el HTML de la página actual.
Vuelve a intentarlo.
Especifica la prioridad relativa para los elementos <link>, <img> y <script>.
Correcto.

¿Cuándo debes usar la sugerencia prefetch?

Para todos los recursos o páginas que el usuario podría necesitar, ya sea que los necesite en el futuro o no.
Vuelve a intentarlo.
Cuando tienes un nivel de confianza alto en que el usuario necesita los recursos o las páginas que quieres precargar.
Correcto.
Si el usuario no indicó una preferencia explícita por reducir el uso de datos
Correcto.

A continuación: Rendimiento de las imágenes

Es probable que a esta altura ya estés familiarizado con tus conocimientos sobre las consideraciones generales de rendimiento en relación con el HTML de la página, el elemento <head> y las sugerencias de recursos. Sin embargo, hay optimizaciones adicionales que son específicas para los diferentes tipos de recursos que suelen cargar las páginas. A continuación, veremos el rendimiento de la imagen en el próximo módulo, que puede ayudarte a lograr que las imágenes de tu sitio web se carguen lo más rápido posible, sin importar el dispositivo del usuario.