馃殌 C贸mo cargar nuestro sitio web m谩s r谩pido

June 27, 2018

Como desarrolladores frontend nuestra meta es brindar mejores experiencias a los usuarios, una de las cosas principales parar lograr esto es hacer que nuestras aplicaciones carguen lo antes posible.

Existen varios estudios con casos reales de empresas que optimizando la carga de su sitio han logrado vender m谩s, tener m谩s visitas, en general impactando la rentabilidad del negocio, as铆 que esto se vuelve un tema cr铆tico.

Imagen de unsplash por Chris Liverani

Para lograr que nuestro sitio sea lo m谩s r谩pido posible podemos usar una gran variedad de t茅cnicas

  • Minificar nuestro c贸digo
  • Comprimir nuestros assets (gzip, brotil, etc)
  • Cargar solo el c贸digo que sea necesario
  • Cargar las im谩genes optimizadas, en el tama帽o necesario, etc
  • Usar lazy loading para cargar im谩genes, evitando cargar im谩genes que no ve el cliente.
  • Usar CDNs que est茅n lo m谩s cerca posible a nuestros clientes
  • Cachear correctamente nuestros assets para no descargarlos m煤ltiples veces
  • Transpilar solo el c贸digo necesario de JS para los navegadores que queremos soportar
  • No bloquear el render de la p谩gina con la carga de assets

Muchos de estos se pueden lograr de forma bastante sencilla usando la herramienta adecuada, pero hoy quiero hablarles de una que a mi parecer no es tan usada y puede tener el mayor impacto con pocas l铆neas de c贸digo.

Preload y Prefetch

Preload y Prefetch son un est谩ndar web que nos permite mejorar el rendimiento de nuestro sitio, tomando el control de cuando se cargan los recursos que son importantes para nosotros.

Preload es como decirle al navegador, 鈥渙ye descarga esto pronto porque el usuario lo va a necesitar de inmediato鈥 y el navegador inicia su descarga a煤n cuanto este leyendo el HTML.

Prefetch es como decirle al navegador, 鈥渙ye descarga esto pero no tiene tanta prioridad鈥, de pronto el usuario lo va a necesitar el recurso en alg煤n punto y el navegador decide cuando es el mejor momento para descargarlo. Si el usuario cambia de vista a煤n as铆 la descarga va a continuar en paralelo.

Recuerda, es importante que no uses esto para cargar todos los recursos de tu sitio. Un gran poder requiere una gran responsabilidad.

驴C贸mo usar preload y prefetch?

Para usarlos debes declararlos usando etiquetas link tan pronto abras el head de tu sitio. Debes usar tres atributos principalmente:

  • rel defines si usar preload o prefetch
  • href la ruta del recurso
  • as el tipo del recurso

As铆, por ejemplo quiere hacer preload de los estilos de tu sitio debes hacer:

<html>
  <head>
    <link rel="preload" href="/static/styles.css" as="styles">
    <link rel="preload" href="app.js" as="script">
    <link rel="stylesheet" href="/static/styles.css">
  </head>
  <body>
    <script src="app.js"></script>
  </body>
</html>

Haciendo este peque帽o cambio podemos ver algunos resultados como las im谩genes a continuaci贸n

en esta primera imagen es el resultado de Lighthouse sin usar preload, en el vemos que la p谩gina se pudo ver m谩s o menos a los 700ms.

Imagen resultado lighthouse sin preload

En la segundo usando preload para los estilos, m谩s o menos a los 300ms ya podemos ver la p谩gina.

Imagen resultado lighthouse con preload

Este ejemplo solo es usando preload en un archivo css, imagina cuantos assets tiene tu proyecto que est谩n bloqueando la carga de tu sitio.

Ahora imagina que alguien entra al home del sitio y sabes que es probable que entre a /about, y est谩s usando code splitting, podr铆as ir haciendo prefetch del script necesario para esa p谩gina.

<html>
  <head>
    <link rel="prefetch" href="about.js" as="script">
  </head>
  <body>
    <h1>Home</h1>
    <a href="/about">Sobre mi</a>
  </body>
</html>

Una vez el usuario entre al home, el navegador en cierto punto va a descargar el script necesario para /about, as铆 la carga de esa p谩gina va a ser mucho m谩s r谩pida.

驴Qu茅 tipos de contenido podemos usar?

  • audio
  • document
  • embed
  • fetch
  • font
  • image
  • object
  • script
  • style
  • track
  • worker
  • video

Cosas a tener en cuenta

  • Si usas preload en recursos que no van a ser usados inmediatamente vas a tener un warning en la consola.
  • Si un recurso ya est谩 cacheado (service workers por ejemplo), no deber铆a volverse a descargar.
  • Puedes ver la prioridad de cada recurso usando el tab network en las herramientas de desarrollo.
  • Si los recursos a los que haces preload/prefetch tienen headers de cach茅 v谩lidos son guardados en cach茅.
  • Cuando cargas fuentes debes usar el atributo crossorigin, as铆 los cargues desde el mismo dominio.
  • No intentes cargar absolutamente todo usando esta t茅cnica.

Fuentes

Uno de los assets m谩s cr铆ticos son las fuentes, y son las que muchas veces bloquean el render de la p谩gina, podemos decirle al navegador que tienen gran importancia y que debe descargarlos pronto

<head>
  <link 
    rel="preload" 
    href="https://fonts.googleapis.com/css?family=Rubik:300,400,500,700"
    as="font"
    crossorigin
  >
  <link href="https://fonts.googleapis.com/css?family=Rubik:300,400,500,700" rel="stylesheet">
</head>

Recuerda tambi茅n usar font-display: swap as铆 el navegador va a mostrar el contenido con la fuente fallback y tan pronto cargue cambiar la fuente, sin bloquear el render

Ahora t茅cnicamente a煤n estamos bloqueando el render de la p谩gina, con los assets cr铆ticos no tenemos opci贸n debemos cargarlos, con preload vamos a lograr que se descarguen lo m谩s pronto posible, pero con assets que no son cr铆ticos podemos cargarlos lazy, sin necesidad de ejecutarlos de inmediato

<body>
  <script>
    var preload = document.createElement("link");
    link.href = "app.js";
    link.rel = "preload";
    link.as = "script";
    document.head.appendChild(link);
  </script>
</body>

y cuando deseemos usarlo, simplemente los inyectas en el sitio.

<body>
  <script>
    var script = document.createElement("script");
    script.src = "app.js";
    document.body.appendChild(script);
  </script>
</body>

Preload elementos de acuerdo a la resoluci贸n

Ya que preload/prefetch usan el tag link, podemos usar el atributo media para personalizar cuando precargamos assets

<link rel="preload" as="image" href="imagen.png" media="(max-width: 600px)">

Con webpack

Si usas webpack para construir tu proyecto tambi茅n puedes usar esta t茅cnica, basta con usar el plugin preload-webpack-plugin y desde la versi贸n 4.6.0, se a帽adi贸 soporte para cuando uses code sppliting puedas usar un magic commet para definir si quieres usar preload o prefetch en ese chunk

import(
  /* webpackChunkName: "modal" */
  /* webpackPrefetch: true */
  "Modal"
)

Palabras finales

Esta forma de manejar los assets la usan proyecto como Next.js o Gatsby.js consiguiendo muy buenos resultados, int茅ntalo en tus proyectos y me cuentas que tan r谩pido carga ahora.