Corregir 'Eliminate render-blocking resources' - Gatsby - Typography - Google Fonts

Ariel Alvarado | Junio 30, 2020


Corriendo Lighthouse sobre el blog, me advierte sobre oportunidades para hacer que el sitio cargue rápidamente. Lighthouse indica que algunos recursos están bloqueando el sitio web evitando que se realice el primer renderizado, en este caso son las fuentes de google (esta solicitud es agregada por Typography.js, ya que el tema que elegí utiliza google fonts).

<link href="//fonts.googleapis.com/css?family=Alegreya+Sans:500|Alegreya:400,400i,700,700i&amp;display=swap" rel="stylesheet" type="text/css" data-gatsby-typography="true">

El primer renderizado es de vital importancia porque afecta a la percepción de los usuarios, si el sitio se renderiza (dibuja) velozmente es menos probable que el usuario cierre la pestaña (aún cuando no sea posible interactuar con el sitio, si el contenido es visible es probable que el usuario se mantenga esperando).

Entonces, tomaremos en cuenta esta sugerencia, pero el tratamiento varia dependiendo si el contenido que bloquea es css o un script.

Cargar scripts asíncronamente

Para scripts (los que no sean críticos y necesarios para el funcionamiento del sitio), se puede utilizar async o defer.

Async se utiliza para indicarle al navegador que el script es independiente de cualquier otro contenido del sitio web (por lo tanto no bloquea que el contenido del sitio se visualice). El contenido es ejecutado en cuanto es descargado incluso si la página web no ha sido parseada completamente. Su forma de uso es bastante simple:

<script async src="http://sitio.maravilloso/archivo-grande.js"></script>

Basta con agregar async al script y el navegador se encarga del resto.

Defer es similar a async, la diferencia es que el contenido del script es ejecutado cuando la página web ha sido parseada por completo. Su forma de uso es también bastante simple:

<script defer src="http://sitio.maravilloso/archivo-grande.js"></script>

Se puede entender mejor el concepto con un diagrama bastante simple:

Bloqueo explicado

Cargar estilos asíncronamente

Para el caso de los estilos, se puede cargar estos asíncronamente de la siguiente manera:

<link rel="preload" as="style" href="estilos-que-bloquean-el-sitio.css" />

Lo nuevo en este caso es rel="preload" as="style", esto le indica al navegador que este estilo se debe cargar lo más pronto posible y de manera asíncrona.

Solucionando el problema en sitio creado con Gatsby

Con toda esta explicación, la forma de solución en Gatsby debería ser simple, pero como estoy utilizando Typography.js tendremos que hacer algo diferente.

El hack que realizaremos será modificar el archivo node_modules\react-typography\dist\GoogleFont.js,

GoogleFont.js
...
if (fontsStr) {
  return _react2.default.createElement("link", {
    href: "//fonts.googleapis.com/css?family=" + fontsStr,
    rel: "preload",
    as: "style",
    type: "text/css",
  });
}
...

La diferencia con el código actual es que se cambio rel: "preload" y se agregó as: "style", con lo cuál queda solucionado el problema.

Obviamente, cuando se vuelvan a instalar los node_modules (npm install) nuestras modificaciones se perderán, así que una posibilidad es clonar el proyecto en un repositorio propio en github y hacer referencia a la librería con este cambio. Otra solución sería guardar los node_modules en github.

Una solución alternativa sería utilizar el plugin preload fonts que agregaría rel="preload" automáticamente a los links, pero me pareció un poco molesto tener hacer correr el script cada vez que agregue un post.

Y eso es todo por ahora, keep coding!!!

Update: En ambiente de producción no fue tan sencilla la solución, presentamos una solución alternativa adentrandonos más en el problema en otro post