¿Cómo optimizar Ruby on Rails para Google Web Vitals?

Mixer Gutiérrez, Group Tech Lead de La Haus nos cuenta cómo junto a su equipo de trabajo han optimizado las páginas principales de su plataforma de compra de vivienda para sus usuarios y Google.

Los Web Vitals son indicadores de calidad que Google considera esenciales para entregar una gran experiencia de usuario en la web, y desde mayo de 2021 están siendo tenidos en cuenta con el ranking de búsqueda.

Cuando participamos en un Google Launchpad en México en 2019 nos llevamos una gran decepción. Nuestra página principal, que tiene pocos elementos interactivos y un contenido en su mayoría estático, tuvo una calificación de 40 puntos sobre 100 en una herramienta llamada PageSpeed Insights lo cual es pésimo.

Para aquellos que no conocen PageSpeed Insights o Web Vitals, acá va una breve descripción:

  • PageSpeed Insights: Herramienta que analiza el contenido de una página web y provee sugerencias para mejorar su velocidad.
  • Web Vitals: Indicadores de calidad que Google considera esenciales para entregar una gran experiencia de usuario en la web.

Tener un sitio veloz es crítico pues hay estudios que correlacionan la demora en el tiempo de carga de una página con pérdida de visitantes, bajo “engagement”, frustración por parte de los usuarios, entre otros.

Teniendo en cuenta la baja velocidad en las conexiones celulares y las bajas especificaciones de los dispositivos móviles en Latinoamérica, reforzamos la importancia de trabajar en este frente.

De vuelta en Colombia, decididos a darle vuelta a la situación, investigamos las razones por tan bajo rendimiento y encontramos dos problemas:

  • Todo el contenido HTML estaba inmerso en nuestros componentes de Vue.js, lo que aumentó el tamaño del Javascript e hizo necesario usar herramientas como Prerender.io para pre-procesar nuestro contenido para Google.
  • Nuestro CSS era enorme. Al usar librerías como Bootstrap, debíamos cargarlo al principio de la página para evitar que se viera terrible en la primera carga.

Luego de lanzar ideas con el equipo, llegamos a las siguientes opciones:

Opción 1: Reescribir todo nuestro Front-End en un framework como Nuxt y usar el Server Side Rendering para solucionar el problema de velocidad e indexación.

Desventajas:

  • No teníamos el ancho de banda en el equipo.
  • No sabíamos cuánto tiempo nos podía tomar reescribirlo todo y cómo afectaría aspectos como manejo de sesiones y rutas de la aplicación.
  • Debíamos parar todos los nuevos features hasta que el nuevo código estuviera al día.

Opción 2: Reescribir nuestros componentes de Front-End en una librería como React on Rails que tiene en sus componentes la opción de Server Side Rendering.

Desventajas:

  • El equipo debía aprender y migrar todo a React.
  • El peso de la librería de React en su momento era alto y se debía asumir dicho costo en la carga de la página incluso si el componente era algo sencillo.

Opción 3: Intentar hacer una librería como React on Rails pero usando Vue.js

Desventajas:

  • No teníamos idea de cómo hacerlo ni sabíamos cuánto nos podía tardar.

Opción 4: Servir el HTML desde Rails y usar Javascript puro para reconstruir las interacciones.

Desventajas:

  • Perder la comodidad y posibilidad de reutilizar plugins y funcionalidades de Vue.js
  • Debíamos contar con desarrolladores experimentados en Javascript para las interacciones más complejas.

¿Qué hicimos?

Luego de hacer pruebas de concepto para cada una de las opciones que teníamos, decidimos arriesgarnos por la opción en la que se usaba el renderizado de HTML desde Rails y se combinaba con un código liviano para el CSS y Javascript.

1. HTML

Una de las ventajas de Ruby on Rails es que tiene la facultad de devolver el HTML listo para Google. Este HTML es indexable y el código puede optimizarse fácilmente para que la respuesta sea lo más rápida posible.

2. CSS

Implementar un CSS eficiente tenía su parte retadora:

  • Si se agrega al final de la etiqueta <body>el sitio se verá sin estilos hasta que el navegador llegue a esa parte, lo descargue y procese.
  • Si se agrega dentro de la etiqueta <head> pero es pesado, se convertirá en un recurso bloqueante al momento de la primera carga de la página y el usuario verá una página en blanco hasta que el navegador termine de descargarlo y procesarlo.

Ambas cosas pueden percibirse durante un par de segundos en una red lenta.

Solución:

  • Usar un framework CSS como TailwindCSS (mucho más liviano que Bootstrap)
  • Inyectar los estilos CSS en nuestro HTML para evitar cargar un recurso externo

3. Javascript

Una vez solucionados los retos del contenido (HTML) y del aspecto visual (CSS) quedaban pendientes los retos de la parte interactiva (Javascript), que no distaban mucho de los anteriores:

  • El código Javascript, dada su complejidad, puede tardar más tiempo en ser procesado que el código CSS, por lo que se debe limitar mucho su uso en la carga inicial.
  • El framework que se use, la cantidad de librerías y la forma como se importan impactan significativamente el peso final del archivo Javascript que se incluye en la página.

Solución:

  • Usar un primer archivo ultraliviano escrito en Javascript puro para la primera carga: lo básico como para ocultar tabs, menús, etc.
  • Usar un segundo archivo de Javascript, activando su descarga y ejecución luego de que el usuario haga alguna interacción (Ej: Scroll, Clic, etc)

¿Qué logramos?