Etiquetas HTML de precarga

Resource Hints: Precarga anticipada de enlaces


Las etiquetas HTML de precarga (resource hints) son una serie de etiquetas <link> que permiten dar al navegador algo de información adicional para saber a que recursos debe darles mayor prioridad, cargar de forma anticipada, posponer o incluso prerenderizar.

Por norma general, el navegador establece una prioridad concreta a cada recurso de una web, ya sea al propio fichero .html inicial, a los archivos .css o .js relacionados con el documento HTML, a las imágenes, tipografías, etc. Esta prioridad depende de una gran variedad de factores y casuísticas complejas, pero se dividen en las siguientes:

  • HIGHEST (Altísima prioridad)
  • HIGH
  • MEDIUM
  • LOW
  • LOWEST (bajísima prioridad)

Etiquetas de precarga

Estos valores se pueden modificar de muchas formas, pero uno de los métodos para modificarlos es utilizar las etiquetas <link> que comentaremos a continuación.

Atributo relDescripción
dns-prefetchIndica un nombre de dominio que debería resolverse lo antes posible.
preconnectIndica una URL a la que debería preconectarse (DNS, handshake, TLS...) lo antes posible.
prefetchIndica una URL que se necesitará en el futuro y debería prepararse.
prerenderIndica una URL que debería renderizarse porque es muy probable que el usuario acceda.
modulepreloadIndica una URL con un módulo Javascript que debe precargar lo antes posible.
preloadIndica una URL que debe precargarse inmediatamente para su utilización posterior.

Veamos como funciona cada uno de ellos en las siguientes secciones.

Recuerda que la optimización es un proceso delicado y complejo. No se trata de añadir una etiqueta de precarga por cada fichero, sino elegir cuales son los que producen cuellos de botella y anticiparlos. Añadir muchas etiquetas de precarga produciría justo el efecto contrario: relentizar la carga.

Por dominio

En primer lugar, veamos las etiquetas que podemos utilizar para precargar los dominios de una URL y conseguir reducir el tiempo de carga del navegador.

Precarga de resolución DNS

Antes de cargar un enlace con un recurso, ya sea una imagen, un fichero css, html o de cualquier otro tipo, el navegador debe resolver las DNS. Básicamente es un proceso que debe hacer al principio de cada recurso que esté alojado en un dominio desconocido, para conocer la IP que está detrás de ese dominio y por lo tanto poderse comunicar de forma más rápida y efectiva.

En muchas ocasiones, esta carga del dominio DNS se realiza muy tarde y se puede perder algún tiempo precioso en ello. Con esta etiqueta, podremos aprovechar «tiempos muertos» iniciales en realizar esa tarea, de modo que cuando descubra esos recursos ya pueda acceder a ellos sin perder el tiempo en resolver el DNS. Es decir, anticipamos esa tarea de resolver DNS.

El código a incluir sería el siguiente:

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

Como se puede ver, en este caso estamos indicando que resuelva las DNS de la página https://fonts.google.com, donde en muchas ocasiones se enlazan tipografías desde nuestro sitio. Ten muy en cuenta que en muchos casos, dentro de estas páginas, se cargan más recursos con nuevos dominios o CDN diferentes que también habría que incluir para que sea 100% efectiva esta tarea.

Preconexión a un dominio

Cada vez que el navegador tiene que realizar la carga de un recurso, por cada dominio debe realizar varias tareas:

  • Búsqueda y resolución de DNS
  • Negociación TCP (Handshake)
  • Negociación TLS (Opcional)

Estas tareas se pueden realizar de forma anticipada para ganar algún tiempo y aprovecharlo en otras tareas.

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

Observa que mientras que la etiqueta anterior sólo realiza el proceso de resolución DNS, esta etiqueta incorpora más etapas, realizando una preconexión al dominio en cuestión.

Por URL

A continuación, veamos algunos ejemplos de etiquetas diseñadas para optimizar la carga de URL o direcciones web específicas.

Prerender

En algunas situaciones, el usuario se encuentra navegando por una página donde, posteriormente, tiene un enlace para acceder a una página donde la probabilidad de acceder es bastante alta. Ejemplos de este caso suelen ser landing page o páginas similares, donde la intención directa es enviar al usuario a una sección específica.

Con la siguiente etiqueta podemos indicar al navegador que esa probabilidad es tan alta, que queremos que la página se vaya no sólo precargando sino prerenderizando de forma transparente en el navegador. Esto hará que cuando el usuario haga click en el enlace, la página esté instantáneamente precargada y predibujada en el navegador.

<head>
  <link rel="prerender" href="https://manz.dev/streams">
</head>

Ten en cuenta que esta etiqueta debe usarse sólo en casos muy específicos donde el usuario es muy probable que acceda, ya que el navegador va a precargar todo su contenido y dibujarlo en el navegador, por lo que si finalmente no entra, habrá desperdiciado tiempo y recursos.

Por recurso

Por último, observa algunas de las etiquetas diseñadas para optimizar la precarga o descarga de ciertos archivos o recursos.

Espera de recurso

La etiqueta <link rel="expect"> se puede utilizar para bloquear el renderizado (dibujado en el navegador) de una página hasta que el elemento indicado en el atributo href esté completamente descargado, parseado y conectado a nuestro documento.

<head>
  <link rel="expect" href="/js/component.js">
</head>

Esto puede ser bastante útil en situaciones donde necesitamos que estén listos ciertos recursos antes de renderizar la página, como un componente o un script específico, evitando que se nos de un error o problema en caso contrario.

Este mecanismo es mucho más interesante en comparación a esperar que cargue toda la página.

Descarga anticipada

Mediante la etiqueta <link rel="prefetch"> podemos indicar al navegador que queremos que un recurso de la página se proponga para ser descargado desde que el navegador tenga tiempo libre en su proceso de carga inicial.

<head>
  <link rel="prefetch" href="https://manz.dev/additional.css" as="styles">
</head>

Observa que es necesario indicar en el atributo as la naturaleza del recurso especificado, ya que de lo contrario el navegador no tiene forma de saber de que tipo de recursos se trata (y muchas veces no se debe confiar en la extensión del fichero). En tipos de recursos puedes ver más información de los valores a utilizar.

Mucho cuidado con confundir prefetch con preload, que aunque tienen un objetivo parecido, hay ciertos matices que los diferencian.

Precarga de archivo

Si lo que necesitamos es realizar la precarga de un archivo por anticipado, la etiqueta <link rel="preload"> es la opción correcta. Esta etiqueta permite precargar recursos inmediatamente, con altísima prioridad. Suele ser una buena práctica para tipografías que utilizas en el primer impacto visual de la página o de imágenes que tienes de cabecera o que producen un parpadeo a la hora de cargarlas.

<head>
  <link rel="preload" href="https://manz.dev/fonts/montserrat.woff2" as="font">
</head>

Observa que esta etiqueta requiere el uso del atributo as, donde deberás indicar el tipo de recurso.

Precarga de módulo

Aunque la etiqueta anterior puede utilizarse para precargar archivos javascript .js, existe una especialización de esta etiqueta denominada <link rel="modulepreload">. Funciona exactamente igual a la etiqueta anterior, sin embargo tiene una pequeña diferencia: además de precargar el recurso, lo añade a la lista de módulos por cargar del navegador, y revisa las dependencias que tiene para precargarlas también, lo que lo hace muy adecuado para módulos Javascript.

<head>
  <link rel="modulepreload" href="https://manz.dev/modules/module.js">
</head>

En este caso, el atributo as tiene por defecto el valor script, por lo que se puede omitir.

Tipos de recursos

En algunas de las etiquetas anteriores habrás comprobado que existe un atributo as donde hay que indicar el tipo de fichero a referenciar. A continuación muestro una tabla con los valores posibles a indicar en este campo:

Atributo asDescripciónFormatos
documentDocumento HTML o enlaces utilizados en elementos <iframe>..html
scriptDocumento Javascript..js
audioArchivo de audio que se puede utilizar en un elemento <audio>..mp3, .ogg, .opus, ...
videoArchivo de video que se puede utilizar en un elemento <video>..mp4, .webm, ...
imageImagen o documento gráfico que es posible utilizar en <img> o <picture>..jpg, .png, .webp, ...
fontTipografía cargada mediante la regla @font-face de CSS..woff2, .woff, .ttf
styleDocumento de estilos CSS..css
trackArchivo de subtítulos utilizado en elementos <track>..vtt
fetchEnlace al que se hace una petición XHR o fetch. Necesita el atributo crossorigin.

Recuerda indicar el valor apropiado en el atributo as, ya que de lo contrario no se sabrá de forma anticipada que tipo de recurso es, y no podrá precargarse el recurso indicado correctamente.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev