Optimiza la carga de recursos con la API de Fetch Priority

La API de Fetch Priority indica la prioridad relativa de los recursos para el navegador. Puede permitir una carga óptima y mejorar las métricas web esenciales.

Navegadores compatibles

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 132.
  • Safari: 17.2.

Origen

Cuando un navegador analiza una página web y comienza a descubrir y descargar recursos, como imágenes, secuencias de comandos o CSS, les asigna un priority de recuperación para que pueda descargarlos en un orden óptimo. La prioridad de un recurso suele depender de qué es y dónde se encuentra en el documento. Por ejemplo, las imágenes en el viewport pueden tener una prioridad High, y la prioridad para el CSS cargado con anticipación que bloquea la renderización con <link> en <head> puede ser Very High. Los navegadores son bastante buenos para asignar prioridades que funcionan bien, pero es posible que no sean óptimas en todos los casos.

En esta página, se analiza la API de Fetch Priority y el atributo HTML fetchpriority, que te permite sugerir la prioridad relativa de un recurso (high o low). Fetch Priority puede ayudar a optimizar las métricas web esenciales.

Resumen

Estas son algunas áreas clave en las que la prioridad de actualización puede ser útil:

  • Aumentar la prioridad de la imagen de LCP especificando fetchpriority="high" en el elemento de imagen, lo que hace que la LCP se produzca antes
  • Aumentar la prioridad de las secuencias de comandos async con una semántica mejor que el hack más común actual (insertar un <link rel="preload"> para la secuencia de comandos async)
  • Disminuye la prioridad de las secuencias de comandos del cuerpo tardío para permitir una mejor secuenciación con imágenes.
Vista de tira de imágenes en la que se comparan dos pruebas de la página principal de Vuelos de Google. En la parte inferior, se usa la prioridad de recuperación para aumentar la prioridad de la imagen hero, lo que genera una disminución de 0.7 segundos en el LCP.
La prioridad de recuperación mejoró la pintura más grande del contenido de 2.6 s a 1.9 s en una prueba de Vuelos de Google.

Históricamente, los desarrolladores tuvieron una influencia limitada sobre la prioridad de los recursos con la carga previa y el preconnect. La precarga te permite informar al navegador sobre recursos críticos que deseas cargar antes de que el navegador los descubra de forma natural. Esto es especialmente útil para los recursos que son más difíciles de descubrir, como las fuentes incluidas en los diseños de plantillas, las imágenes de fondo o los recursos cargados desde una secuencia de comandos. La conexión previa ayuda a preparar las conexiones a servidores de varios orígenes y puede mejorar métricas como el tiempo hasta el primer byte. Es útil cuando conoces un origen, pero no necesariamente la URL exacta de un recurso que se necesitará.

La prioridad de recuperación complementa estas sugerencias de recursos. Es un indicador basado en el marcado disponible a través del atributo fetchpriority que los desarrolladores pueden usar para indicar la prioridad relativa de un recurso en particular. También puedes usar estas sugerencias a través de JavaScript y la API de Fetch con la propiedad priority para influir en la prioridad de las recuperaciones de recursos realizadas para los datos. La prioridad de recuperación también puede complementar la carga previa. Toma una imagen de procesamiento de imagen con contenido más grande que, cuando se precargue, seguirá teniendo una prioridad baja. Si otros recursos de prioridad baja la retrasan, usar la prioridad de recuperación puede ayudar a determinar la rapidez con la que se carga la imagen.

Prioridad de los recursos

La secuencia de descarga de recursos depende de la prioridad asignada por el navegador para cada recurso de la página. Entre los factores que pueden afectar la lógica de cálculo de prioridad, se incluyen los siguientes:

  • Es el tipo de recurso, como CSS, fuentes, secuencias de comandos, imágenes y recursos de terceros.
  • La ubicación o el orden en el que el documento hace referencia a los recursos
  • Si se usan los atributos async o defer en las secuencias de comandos

En la siguiente tabla, se muestra cómo Chrome prioriza y secuencia la mayoría de los recursos:

  Carga en la fase de bloqueo del diseño Carga uno a la vez en la fase de bloqueo del diseño
Prioridad
de Blink
VeryHigh Alta Versión intermedia Bajo VeryLow
Herramientas para desarrolladores
Prioridad
Más alta Alta Versión intermedia Bajo Más bajo
Recurso principal
CSS (temprano**) CSS (a fines de**) CSS (discrepancia de medios***)
Secuencia de comandos (temprana** o no desde el escáner de carga previa) Guion (tardío**) Secuencia de comandos (asíncrona)
Fuente Fuente (rel=preload)
Importar
Imagen (en la ventana de visualización) Imagen (las primeras 5 imágenes > 10,000 px2) Imagen
Contenido multimedia (video/audio)
Recuperación previa
XSL
XHR (síncrono) XHR/recuperación* (asíncrono)

El navegador descarga los recursos con la misma prioridad calculada en el orden en que se descubren. Puedes verificar la prioridad asignada a los diferentes recursos cuando cargas una página en la pestaña Red de las herramientas para desarrolladores de Chrome. (Asegúrate de incluir la columna priority haciendo clic con el botón derecho en los encabezados de la tabla y marcándola).

Pestaña Network de las herramientas para desarrolladores de Chrome, en la que se enumeran varios recursos de fuentes. Todas tienen la prioridad más alta.
Prioridad para el recurso type = "font" en la página de detalles de las noticias de la BBC
Pestaña Network de las herramientas para desarrolladores de Chrome, en la que se enumeran varios recursos de fuentes. Son una combinación de prioridad baja y alta.
Prioridad para el recurso type = "script" en la página de detalles de las noticias de la BBC.

Cuando cambian las prioridades, puedes ver la prioridad inicial y la final en el parámetro de configuración Big request rows o en una herramienta de ayuda.

Pestaña Red de las Herramientas para desarrolladores de Chrome. Se marcó el parámetro de configuración &quot;Big request rows&quot; y la columna Priority muestra la primera imagen con una prioridad de Alta y una prioridad inicial diferente de Media debajo. Lo mismo se muestra en la información sobre la herramienta.
Cambios de prioridad en DevTools.

¿Cuándo podrías necesitar la prioridad de actualización?

Ahora que comprendes la lógica de priorización del navegador, puedes ajustar el orden de descarga de tu página para optimizar su rendimiento y las Métricas web esenciales. Estos son algunos ejemplos de lo que puedes cambiar para influir en la prioridad de las descargas de recursos:

  • Coloca etiquetas de recursos, como <script> y <link>, en el orden en que deseas que el navegador las descargue. Por lo general, los recursos con la misma prioridad se cargan en el orden en que se descubren.
  • Usa la sugerencia de recursos preload para descargar los recursos necesarios con anticipación, en especial para los recursos que el navegador no descubre fácilmente con anticipación.
  • Usa async o defer para descargar secuencias de comandos sin bloquear otros recursos.
  • Carga diferida del contenido de la mitad inferior de la página para que el navegador pueda usar el ancho de banda disponible para los recursos más críticos de la mitad superior de la página.

Estas técnicas ayudan a controlar el procesamiento de prioridad del navegador, lo que mejora el rendimiento y las Métricas web esenciales. Por ejemplo, cuando se precarga una imagen de fondo crítica, se puede descubrir mucho antes, lo que mejora el procesamiento de imagen con contenido más grande (LCP).

A veces, estos identificadores pueden no ser suficientes para priorizar los recursos de forma óptima para tu aplicación. Estas son algunas de las situaciones en las que la prioridad de actualización podría ser útil:

  • Tienes varias imágenes en la mitad superior de la página, pero no todas deben tener la misma prioridad. Por ejemplo, en un carrusel de imágenes, solo la primera imagen visible necesita una prioridad más alta, y las demás, que suelen estar fuera de la pantalla al principio, se pueden configurar para que tengan una prioridad más baja.
  • Por lo general, las imágenes dentro de la ventana de visualización comienzan con una prioridad Low. Una vez que se completa el diseño, Chrome descubre que se encuentra en el viewport y aumenta su prioridad. Esto suele agregar una demora significativa a la carga de las imágenes críticas, como las imágenes hero. Proporcionar la prioridad de recuperación en el marcado permite que la imagen comience con una prioridad High y comience a cargarse mucho antes. Para automatizar esto un poco, Chrome establece las primeras cinco imágenes más grandes en la prioridad Medium, lo que ayudará, pero un fetchpriority="high" explícito será aún mejor.

    La carga previa sigue siendo necesaria para el descubrimiento anticipado de las imágenes de LCP incluidas como fondos de CSS. Para aumentar la prioridad de tus imágenes de fondo, incluye fetchpriority='high' en la carga previa.
  • Declarar secuencias de comandos como async o defer le indica al navegador que las cargue de forma asíncrona. Sin embargo, como se muestra en la tabla de prioridades, a estas secuencias de comandos también se les asigna una prioridad "Baja". Te recomendamos que aumentes su prioridad y, al mismo tiempo, garantices la descarga asíncrona, especialmente para las secuencias de comandos que son fundamentales para la experiencia del usuario.
  • Si usas la API de fetch() de JavaScript para recuperar recursos o datos de forma asíncrona, el navegador le asigna la prioridad High. Es posible que desees que algunas de tus recuperaciones se ejecuten con una prioridad más baja, especialmente si combinas llamadas a la API en segundo plano con llamadas a la API que responden a la entrada del usuario. Marca las llamadas a la API en segundo plano como prioridad Low y las llamadas a la API interactivas como prioridad High.
  • El navegador asigna una prioridad High a los CSS y las fuentes, pero algunos de esos recursos pueden ser más importantes que otros. Puedes usar la prioridad de recuperación para disminuir la prioridad de los recursos no críticos (ten en cuenta que el CSS anticipado bloquea la representación, por lo que, por lo general, debe tener una prioridad High).

El atributo fetchpriority

Usa el atributo HTML fetchpriority para especificar la prioridad de descarga de tipos de recursos, como CSS, fuentes, secuencias de comandos e imágenes, cuando se descargan con etiquetas link, img o script. Puede tener los siguientes valores:

  • high: El recurso tiene una prioridad más alta y deseas que el navegador lo priorice más de lo habitual, siempre y cuando las propias heurísticas del navegador no lo impidan.
  • low: El recurso tiene una prioridad más baja y deseas que el navegador lo despriorice, de nuevo, si sus heurísticas lo permiten.
  • auto: Es el valor predeterminado, que permite que el navegador elija la prioridad adecuada.

Estos son algunos ejemplos del uso del atributo fetchpriority en el lenguaje de marcado, así como la propiedad priority equivalente a la secuencia de comandos.

<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">

<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">

<script>
  fetch('https://example.com/', {priority: 'low'})
  .then(data => {
    // Trigger a low priority fetch
  });
</script>

Efectos de la prioridad del navegador y fetchpriority

Puedes aplicar el atributo fetchpriority a diferentes recursos, como se muestra en la siguiente tabla, para aumentar o reducir su prioridad calculada. fetchpriority="auto" (◉) en cada fila marca la prioridad predeterminada para ese tipo de recurso. (también está disponible como Documento de Google).

  Carga en la fase de bloqueo del diseño Carga uno a la vez en la fase de bloqueo del diseño
Prioridad
de Blink
VeryHigh Alta Versión intermedia Bajo VeryLow
Herramientas para desarrolladores
Prioridad
Más alta Alta Versión intermedia Bajo Más bajo
Recurso principal
CSS (temprano**) ⬆◉
CSS (a fines de**)
CSS (discrepancia de medios***) ⬆*** ◉⬇
Secuencia de comandos (temprana** o no del escáner de carga previa) ⬆◉
Guion (tardío**)
Secuencia de comandos (asincrónica/diferida) ◉⬇
Fuente
Fuente (rel=preload) ⬆◉
Importar
Imagen (en la ventana de visualización, después del diseño) ⬆◉
Imagen (las primeras 5 imágenes > 10,000 px2)
Imagen ◉⬇
Contenido multimedia (video/audio)
XHR (sincronización): obsoleto
XHR/recuperación* (asíncrono) ⬆◉
Recuperación previa
XSL

fetchpriority establece la prioridad relativa, lo que significa que aumenta o disminuye la prioridad predeterminada en una cantidad adecuada, en lugar de establecer la prioridad explícitamente en High o Low. Esto suele generar una prioridad High o Low, pero no siempre. Por ejemplo, el CSS crítico con fetchpriority="high" conserva la prioridad "Muy alta" o "Más alta", y el uso de fetchpriority="low" en estos elementos conserva la prioridad "Alta". Ninguno de estos casos implica establecer explícitamente la prioridad en High o Low.

Casos de uso

Usa el atributo fetchpriority cuando quieras darle al navegador una sugerencia adicional sobre con qué prioridad recuperar un recurso.

Aumenta la prioridad de la imagen de LCP

Puedes especificar fetchpriority="high" para aumentar la prioridad del LCP o de otras imágenes críticas.

<img src="lcp-image.jpg" fetchpriority="high">

En la siguiente comparación, se muestra la página de Vuelos de Google con una imagen de fondo de LCP cargada con y sin prioridad de recuperación. Con la prioridad establecida en alta, el LCP mejoró de 2.6 s a 1.9 s.

Un experimento realizado con trabajadores de Cloudflare para reescribir la página de Vuelos de Google con la prioridad de recuperación.

Usa fetchpriority="low" para disminuir la prioridad de las imágenes de la mitad superior de la página que no son importantes de inmediato, por ejemplo, las imágenes fuera de la pantalla en un carrusel de imágenes.

<ul class="carousel">
  <img src="img/carousel-1.jpg" fetchpriority="high">
  <img src="img/carousel-2.jpg" fetchpriority="low">
  <img src="img/carousel-3.jpg" fetchpriority="low">
  <img src="img/carousel-4.jpg" fetchpriority="low">
</ul>

Si bien las imágenes 2 a 4 estarán fuera del viewport, se pueden considerar "suficientemente cercanas" para aumentarlas a high y también cargarlas, incluso si se agrega un atributo load=lazy. Por lo tanto, fetchpriority="low" es la solución correcta para esto.

En un experimento anterior con la app de Oodle, usamos esto para disminuir la prioridad de las imágenes que no aparecen durante la carga. Se redujo el tiempo de carga de la página en 2 segundos.

Comparación en paralelo de la prioridad de recuperación cuando se usa en el carrusel de imágenes de la app de Oodle. A la izquierda, el navegador establece prioridades predeterminadas para las imágenes del carrusel, pero descarga y pinta esas imágenes alrededor de dos segundos más lento que el ejemplo de la derecha, que establece una prioridad más alta solo en la primera imagen del carrusel.
Si usas prioridad alta solo para la primera imagen del carrusel, la página se cargará más rápido.

Disminuye la prioridad de los recursos precargados

Para evitar que los recursos precargados compitan con otros recursos críticos, puedes reducir su prioridad. Usa esta técnica con imágenes, secuencias de comandos y CSS.

<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" as="script" href="non-critical-script.js" fetchpriority="low">

<!-- Preload CSS without blocking render, or other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">

Cómo volver a establecer la prioridad de las secuencias de comandos

Las secuencias de comandos que necesita tu página para ser interactiva deben cargarse rápidamente, pero no deben bloquear otros recursos más críticos que bloquean la renderización. Puedes marcarlos como async con prioridad alta.

<script src="async_but_important.js" async fetchpriority="high"></script>

No puedes marcar una secuencia de comandos como async si depende de estados de DOM específicos. Sin embargo, si se ejecutan más adelante en la página, puedes cargarlos con una prioridad más baja:

<script src="blocking_but_unimportant.js" fetchpriority="low"></script>

De esta manera, se bloqueará el analizador cuando llegue a esta secuencia de comandos, pero se permitirá que se priorice el contenido anterior.

Una alternativa, si se necesita el DOM completo, es usar el atributo defer (que se ejecuta, en orden, después de DOMContentLoaded) o incluso async en la parte inferior de la página.

Disminuye la prioridad de las recuperaciones de datos no críticos

El navegador ejecuta fetch con una prioridad alta. Si tienes varias recuperaciones que pueden activarse de forma simultánea, puedes usar la prioridad predeterminada alta para las recuperaciones de datos más importantes y disminuir la prioridad de los datos menos importantes.

// Important validation data (high by default)
let authenticate = await fetch('/user');

// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});

Cómo recuperar notas de implementación de prioridad

La prioridad de actualización puede mejorar el rendimiento en casos de uso específicos, pero debes tener en cuenta lo siguiente cuando la uses:

  • El atributo fetchpriority es una sugerencia, no una directiva. El navegador intenta respetar la preferencia del desarrollador, pero también puede aplicar sus preferencias de prioridad de recursos para resolver conflictos.
  • No confundas la prioridad de recuperación con la carga previa:

    • La precarga es una recuperación obligatoria, no una sugerencia.
    • La precarga permite que el navegador descubra un recurso con anticipación, pero aún recupera el recurso con la prioridad predeterminada. Por el contrario, la prioridad de actualización no ayuda con la visibilidad, pero te permite aumentar o disminuir la prioridad de actualización.
    • A menudo, es más fácil observar y medir los efectos de una carga previa que los efectos de un cambio de prioridad.

    La prioridad de recuperación puede complementar las cargas previas aumentando el nivel de detalle de la priorización. Si ya especificaste una carga previa como uno de los primeros elementos en <head> para una imagen de LCP, es posible que una prioridad de recuperación high no mejore significativamente el LCP. Sin embargo, si la precarga se produce después de que se cargan otros recursos, una prioridad de recuperación de high puede mejorar más el LCP. Si una imagen crítica es una imagen de fondo de CSS, cárgala previamente con fetchpriority = "high".

  • Las mejoras en el tiempo de carga que se obtienen con la priorización son más relevantes en entornos en los que más recursos compiten por el ancho de banda de red disponible. Esto es común para las conexiones HTTP/1.x en las que no son posibles las descargas en paralelo o en las conexiones HTTP/2 o HTTP/3 de ancho de banda bajo. En estos casos, la priorización puede ayudar a resolver los cuellos de botella.

  • Las CDN no implementan la priorización de HTTP/2 de forma uniforme, y lo mismo sucede con HTTP/3. Incluso si el navegador comunica la prioridad de la prioridad de recuperación, es posible que la CDN no vuelva a priorizar los recursos en el orden especificado. Esto dificulta la prueba de la prioridad de recuperación. Las prioridades se aplican de forma interna en el navegador y con protocolos que admiten la priorización (HTTP/2 y HTTP/3). Aún vale la pena usar la prioridad de recuperación solo para la priorización interna del navegador, independientemente de la compatibilidad con CDN o el origen, ya que las prioridades suelen cambiar cuando el navegador solicita recursos. Por ejemplo, los recursos de baja prioridad, como las imágenes, a menudo no se solicitan mientras el navegador procesa elementos <head> críticos.

  • Es posible que no puedas implementar la prioridad de recuperación como práctica recomendada en tu diseño inicial. Más adelante en tu ciclo de desarrollo, puedes ver las prioridades que se asignan a los diferentes recursos de la página y, si no cumplen con tus expectativas, puedes implementar la prioridad de recuperación para realizar una mayor optimización.

Los desarrolladores deben usar la carga previa para su propósito previsto: precargar recursos que el analizador no detecta (fuentes, importaciones, imágenes de LCP en segundo plano). La ubicación de la sugerencia preload afectará el momento en que se precargará el recurso.

La prioridad de recuperación se refiere a cómo se debe recuperar el recurso cuando se recupera.

Sugerencias para usar las cargas previas

Ten en cuenta lo siguiente cuando uses cargas previas:

  • Si incluyes una carga previa en los encabezados HTTP, esta se coloca antes de todo lo demás en el orden de carga.
  • Por lo general, las cargas previas se cargan en el orden en que el analizador las recibe para cualquier elemento con prioridad Medium o superior. Ten cuidado si incluyes cargas previas al comienzo de tu código HTML.
  • Es probable que las cargas previas de fuentes funcionen mejor al final de la cabecera o al comienzo del cuerpo.
  • Las cargas previas de importación (import() o modulepreload dinámicos) deben ejecutarse después de la etiqueta de secuencia de comandos que necesita la importación, por lo que debes asegurarte de que la secuencia de comandos se cargue o analice primero para que se pueda evaluar mientras se cargan sus dependencias.
  • La carga previa de imágenes tiene una prioridad Low o Medium de forma predeterminada. Ordénalas en relación con las secuencias de comandos asíncronas y otras etiquetas de prioridad baja o más baja.

Historial

La prioridad de recuperación se probó por primera vez en Chrome como una prueba de origen en 2018 y, luego, nuevamente en 2021 con el atributo importance. En ese momento, se llamaban Sugerencias de prioridad. Desde entonces, la interfaz cambió a fetchpriority para HTML y priority para la API de Fetch de JavaScript como parte del proceso de estándares web. Para reducir la confusión, ahora llamamos a esta API Priority Fetch.

Conclusión

Es probable que a los desarrolladores les interese la prioridad de recuperación con las correcciones en el comportamiento de carga previa y el enfoque reciente en las métricas web esenciales y la LCP. Ahora tiene perillas adicionales disponibles para lograr su secuencia de carga preferida.