This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Esta es la web de Fotocasa en móvil. Gracias a las herramientas de desarrollo podemos ver que
se ha descargado dos archivos CSS de 7 y 14 kilobytes respectivamente, pero ¿cuánto de
esto está utilizando realmente el navegador para renderizar nuestra página? Lo podemos saber
usando las herramientas CodeCoverage de las Chrome Developer Tools. Si le damos al botón
de recargar, nos recargará la página y capturará la cobertura de nuestro código, tanto de
JavaScript como de CSS. Una vez que termine, nos indicará de forma muy gráfica qué tanto
por ciento del código ha utilizado. Y los resultados duelen un poco. En el caso del CSS, más de
un 70% de ambos archivos no se está utilizando. Y eso es bastante. Sobre todo si tenemos en
cuenta que el CSS es un recurso que bloquea el renderizado de nuestra página web y, por
lo tanto, optimizar cuánto se tiene que descargar el usuario es vital para poder impactar en
el First Paint. Lo ideal sería servir ese 30% que sí utiliza la página y el resto del
CSS cargarlo de forma síncrona. Pero, ¿cómo podemos extraer ese CSS que sí se usa de forma
automática? Pues vamos a hacerlo ahora mismo. En una terminal, en la carpeta que queráis,
por ejemplo, Critical CSS, vamos a crear un proyecto de Node. Para eso, usaremos el comando
npm init y le pasaremos el parámetro y para que nos dé por buenos todos los valores por
defecto. Como dependencia de nuestro proyecto, solo tendremos pappetier. Para instalarla,
ejecutaremos el comando npm install pappetier. Si no lo conoces, es una librería de Google
que nos proporciona una API a muy alto nivel para poder controlar un navegador Chrome de
forma programática en Node. Y ahora, con vuestro editor favorito, vamos a crear un archivo index.js
la raíz del proyecto. Lo primero que hacemos es requerir la dependencia de pappetier para poder
utilizarla. Luego, creamos una forma bastante rudimentaria, pero interesante, para conseguir
que podamos utilizar diferentes URLs con nuestro programa, utilizando las variables de entorno.
Y ahora, empieza la magia. Tienes que saber que la API de pappetier es totalmente asíncrona y basada
en promesas, por lo que vamos a crear una función que se invoca inmediatamente con una sync que nos
permita utilizar async await en nuestro código y mejorar la legibilidad del mismo.
Dentro de la función asíncrona, primero creamos una instancia de un navegador. Le pasaremos como
opciones que lo queremos headless, para que no nos abra la ventana visual del navegador. Y en ese
mismo navegador, abriremos una página donde luego iremos a la URL. Pappetier también nos permite
controlar y acceder a muchas funciones de las Chrome Developer Tools. Y una de ellas es el Code
Coverage que hemos visto antes. Para indicarle que queremos empezar a capturar el código CSS
que usa, tendremos que ejecutar el método startCSSCoverage de la propiedad Coverage de
la página. Y ya solo nos queda navegar a la URL que queramos. Lo interesante aquí es que usando
la opción Wait Until, podemos indicarle al navegador qué evento esperamos para dar por
cargada a la página. Podéis utilizar, por ejemplo, el evento DOMContentLoad, pero es posible
que algunos elementos no se hayan cargado todavía en ese punto. Lo malo del load, pues
que va a tardar unos segundos más en ejecutarse nuestro script. Así que vosotros decidís cuál
de los dos os va mejor. Sigamos con nuestro script. En este punto, el navegador ya habrá
cargado la página y ya podemos parar el script de la cobertura del CSS para recuperar los
datos. Ahora, en esta constante CSSCoverage tenemos toda la información sobre la cobertura
CSS de esa página. Así que solo falta extraer esa información tan valiosa de este objeto.
¿Y cómo lo hacemos? Pues vamos a iterarlo. En CSSCoverage vamos a iterar todas las entradas
que tiene. Cada entrada es un archivo CSS y dentro de cada entrada nos devuelve los rangos
del archivo que se está usando para renderizar la página. Ahora, para todos los rangos, lo
que hacemos es ir concatenando esa información en una variable llamada CriticalCSS. Para recuperar
la información, usamos el punto de inicio y el punto final del rango en el texto del
CSS para extraerlo. Y para separar mejor, le añadimos un salto de línea al final. Vale,
cuando terminan los dos bucles, ya deberíamos tener en la variable CriticalCSS toda la información.
Así que vamos a escupirla por la consola para ver que todo ha funcionado correctamente. Eso
sí, antes de irnos, vamos a hacer una cosa más. Cerrar la página y el navegador que hemos
dejado de usar. Bueno, bueno, vamos a ver si esto funciona. Volvemos a la terminal y ejecutamos
nuestro archivo con node.index.js. Había puesto por defecto que sacase el CSS crítico de la
web de Fotocasa y ahí lo tenemos. Eso es todo el CSS que necesita Fotocasa para renderizarse,
que sigue siendo una buena cantidad. Vamos a probar a extraer ahora el CSS crítico de Google
usando la variable de entorno URL. Y ahí está. Se nota que el de Google es bastante
más simple. Voy a probar con mi propio blog a ver qué tal y ahí lo tenemos. Eso es todo
el CSS que se está usando al renderizar mi blog. Por eso nunca veremos ahí ni los hover,
ni media queries, ni nada de eso. Por si os interesa, podéis hacer una redirección de la salida
de la consola a un fichero directamente para que os lo guarde en un archivo CSS, por ejemplo.
Aunque lo suyo es que este CSS que veis, que estáis viendo, pues lo pongáis en línea en
vuestra página.
Y eso es todo. Solo que sepáis que he escrito un artículo en mi blog midudev.com con mucha
más información sobre qué es el Critical Path y donde explico paso a paso cómo lo podéis
hacer. Y antes de irme, no me digáis que no es bonito que en menos de 20 líneas de código
hemos creado una herramienta tan potente. Pues si te ha gustado, dale al like, suscríbete
y compártelo con tus amigos y colegas. Nos vemos en el próximo.