Optimizar tiempos de carga web en archivos CSS
Uno de los aspectos más representativos en el tiempo de carga de una página web son sus archivos CSS. La razón es simple, los navegadores paran el rederizado de la página hasta no haber cargado, parseado y ejecutado cada uno de los archivos CSS dentro de la etiqueta head. Esto significa, que si dentro de la etiqueta head cargas un archivo CSS demasiado grande la página tardará en mostrarse lo que tarde ese archivo en descargarse. Esto puede suponer un tiempo en el que la página web esté en blanco y puede llegar a ser suficiente para que un usuario haga clic en el botón Atrás y se dirija a otra web.
Lo anterior es conocido como Render-blocking CSS, o CSS que bloquea la presentación. Si bien es cierto que algunos estilos son estrictamente necesarios y su falta supondría pérdida de funcionalidad de la página, otros no son tan esenciales y pueden cargarse solo cuando sean necesarios. A continuación, veremos algunos casos en los que podemos optimizar los tiempos de carga de estos archivos CSS basados en esta premisa.
Tipo y consultas de medios CSS
El tipo y las consultas de medios son esenciales para saber cuándo se carga un CSS. Veamos algunos ejemplos.
<link href="style.css" rel="stylesheet">
<link href="style.css" rel="stylesheet" media="all">
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">
<link href="portr.css" rel="stylesheet" media="orientation:portrait">
1. La primera declaración bloquea la presentación debido a que si no se especifica el atributo media el browser asume por defecto el valor all, es decir, todos los medios. En cualquier caso el CSS se cargará.
2. La segunda declaración define de manera explícita todos los medios, por lo cual es exactamente igual al ejemplo anterior y bloquea siempre la presentación.
3. La tercera declaración no bloquea la presentación debido a que solo se aplica durante la impresión de la página. Haría falta que el usuario intente imprimir la página para que dicho evento lanzara la carga del CSS.
4. La cuarta declaración bloqueará la presentación cuando se presente la condición especificada.
5. La última declaración podría bloquear la presentación dependiendo de la orientación del dispositivo al momento de cargar la página. Si la página se carga en portrait bloqueará la presentación.
Precargar Recursos
Ya se dijo que por defecto los navegadores tratan los archivos CSS como recursos que bloquean la presentación. Sin embargo, existe una forma de realizar la carga de estos recursos de manera asíncrona. Veamos un ejemplo cargando fuenes externas en una página web.
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">
El código anterior muestra una forma muy común de cargar una fuente de Google. El problema con esto, es que deja el FCP (first contentful paint) después de la carga de las fuentes. El FCP es el primer pantallazo que se muestra al usuario. En la siguiente imagen podrás darte cuenta que el FCP está alrededor de los 240 ms cargando tres fuentes de Google. Antes de eso la página está en blanco como puedes corroborar en las previsualizaciones en miniatura.
La forma de cargar este recurso de manera asíncrona es la siguiente:
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap"
rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
Como puedes darte cuenta el cambio realizado está en el atributo rel="preload"
. Además de esto hay que indicarle al navegador qué tipo de recurso se va a cargar, en este caso as="style"
. El atributo onload
se asegura que el CSS sea procesado cuando termina de cargar y el valor null
en la asignación evita que en algunos browsers se cargue dos veces. A continuación podemos ver el cambio en performance una vez se realiza el cambio.
El FCP ha pasado a posicionarse alrededor de los 100 ms. Adicional a esto, podríamos agregar el siguiente código en caso de que el navegador no tenga habilitado Javascript.
<noscript>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">
</noscript>
Un vistazo a los reportes del Lighthouse de Google nos puede dar un panorama más completo acerca de los recursos que bloquean la presentación en una página web.
Aunque esto podría parecer suficiente, te invito a revisar nuestro artículo Qué es el CSS Crítico y cómo puede optimizar el FCP ? para profundizar aún más en el redimiento de recursos que bloquean la presentación. Nos vemos allá!.