Políticas de obtención de recursos

31 de julio de 2021

Yo le llamo así. Se trata de definir la forma en la que un navegador web gestiona la descarga y ejecución de algunos tipos de recursos en una web.

Entre estas políticas podemos pensar en cuándo el navegador va a descargar una imagen, un vídeo o un iframe; en si va a ser necesario que descargue todas las hojas de estilo, o si necesita descargarlas antes de empezar a renderizar el contenido.

Ídem con los scripts: ¿Cómo son de necesarios? ¿Pueden esperar? ¿Hay alguna dependencia entre ellos?

Cómo se carga una web

El proceso de carga de una web transcurre más o menos de la siguiente manera:

Una vez que se ha resuelto el DNS, hecho la petición al servidor, negociado los certificados y claves de cifrado, etc.

  1. El cliente (navegador), obtiene el contenido html y comienza a procesarlo de arriba hacia abajo.
  2. Cuando encuentra un recurso, como un <script> o un <link> css, se detiene y pide al servidor el nuevo recurso.
  3. Cuando obtiene ese recurso, supongamos un css, lo lee e interpreta. Aquí, si encuentra un @import de otro css, se para, se lo pide al servidor… (Por eso es que se suelen llamar «solicitudes que bloquean la carga del contenido»).
  4. Al finalizar de procesar cada recurso, sigue con el siguiente.

Carga diferida de elementos (Lazy-load)

Desde no hace mucho, los navegadores manejan la carga diferida de algunos elementos, como son imágenes, iframes o embeds.

Esto se consigue estableciendo el atributo «loading=”lazy”» en la etiqueta html correspondiente.

<img src="//url.de/la/imagen.jpg" 
loading="lazy" 
alt="texto alternativo" 
width="320" 
height="240">Lenguaje del código: HTML, XML (xml)

Para que funcione correctamente, debe establecerse el tamaño que la imagen, o el recurso que sea, va a ocupar en la página, en la propia etiqueta html.

Ten en cuenta la accesibilidad en las imágenes y no olvides cubrir convenientemente el atributo alt en éstas y en los elementos iframe y embed.

Ya hablé de cómo mejorar el uso de las imágenes en web anteriormente y también de algunas formas sobre cómo se pueden gestionar las imágenes en WordPress. No tiene mucho sentido que me pare ahora con esto.

Carga con bloqueo, asíncrona o diferida de los scripts

En algunos casos no es esencial que se carguen los scripts desde el principio. Las funcionalidades que aportan estos no son necesarias desde el comienzo de la carga de la web y podría no ser necesario esperar a la descarga o incluso podrían ser ejecutados al final de la carga de la página sin implicar una pérdida en cuanto a la experiencia del usuario.

Aquí, vienen al rescate los atributos async y defer. Con ellos puedes indicar al navegador que:

  • retrase la carga al final, cuando todo lo principal esté ya cargado, usando defer,
  • continúe con la carga del resto del documento sin esperar a que este recurso esté listo, con async.

Dicho de otra forma:

  • Con defer no pedirá el recurso hasta que todo lo demás esté cargado. Además, defer matendrá el orden de ejecución de los scripts, evitando algunos problemas de dependencia entre ellos. Por ejemplo, bootstrap depende de jquery. Si se intenta ejecutar antes de que jquery esté listo, obtendremos un bonito error.
  • Con async, el navegador pedirá el recurso, pero no se quedará esperando a obtenerlo, sino que seguirá cargando el resto de elementos. Cuando el script haya sido descargado, detendrá lo que esté haciendo, ejecutará el script y continuará. Aquí, no atiende a dependencias, ejecuta el script cuando esté descargado. Si este dependiese de otro, y este otro no hubiese sido cargado aún, error.

Hay que tener en cuenta, también, que puede haber código incrustado dependiente de algún script. Nuevamente, es común que haya pequeños scripts entre el html que, por comodidad, hacen uso de jQuery. Si lo marcamos como defer… éstos no van a poder ejecutarse correctamente.

Obtención temprana de los recursos

Si conoces de antemano que ciertos recursos van a ser necesarios, y que van a ser necesarios lo más pronto posible, puedes forzar la precarga de éstos para adelantarte a que el navegador las tenga que pedir.

Preload y prefetch

<link rel="preload" href="/fonts/mifuente.ttf" type="font" crossorigin>Lenguaje del código: HTML, XML (xml)
<link rel="prefetch" href="/fonts/mifuente.ttf" type="font" crossorigin>Lenguaje del código: HTML, XML (xml)

Actualización:

Las pruebas que había hecho, nunca me habían funcionado del todo bien. Sí, los recursos se precargaban, pero no se usaban después sino que se descargaban de nuevo.

¿El problema? La ruta href debe ser exactamente la misma que la ruta usada al cargar la fuente, incluyendo el protocolo, el dominio, e incluso los parámetros GET. Quedará, entonces, algo como:

<link rel="preload"
href="https://www.midomin.io/fonts/mifuente.woff2" type="font" 
crossorigin>

<style>
@font-face {
  font-family: 'Mi fuente chachiguay';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://www.midomin.io/fonts/mifuente.woff2) format('woff2'),
       url(https://www.midomin.io/fonts/mifuente.ttf) format('truetype');
}
</style>Lenguaje del código: HTML, XML (xml)

Adelantarse a los acontecimientos

Por otro lado, si sabes que vas a tener que obtener recursos desde otros dominios, también estaría bien, desde un principio, ir resolviendo los DNS o preestableciendo conexión con esos dominios. Para esto se usará dns-prefectch o preconnect.

dns-prefetch y preconnect

<link rel="dns-prefetch" href="https://googletagmanager.com">Lenguaje del código: HTML, XML (xml)
<link rel="preconnect" href="https://cdn.fontawesome.com">Lenguaje del código: HTML, XML (xml)

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.