Este año, Habitissimo cumplirá once años. Once años es bastante tiempo en la web, las cosas han cambiado, han avanzado, y a día de hoy, siguen evolucionando. Es por eso que día a día asumimos grandes nuevos desafíos. 

Hoy os vengo a hablar acerca de unos de los desafíos al cual nos hemos enfrentado:  disminuir el tiempo de carga de la web, y concretamente de la sección Guía de Precios debido al tráfico que recibe (~1 millón de visitas mensualmente).

Pero primero que nada un poco de historia

Tras estos años, a nivel técnico y de producto ha provocado:

1. Uso de librerías o frameworks que a día de hoy ya están deprecados o no soportados.
¿Quién no se acuerda de la librería como modernizr? Maquetar en tablas o usar ficheros png para simular sombras, bordes, etc. Por suerte, esos tiempos han quedado atrás.

2. Dar compatibilidad a navegadores deprecados.


A finales de 2009 el navegador más usado era ¡IE 8! por tanto, nuestros desarrollos partían de que debían ser compatibles con esos navegadores.

Si volvemos de nuevo al presente:

¡Han desaparecido completamente esos grandes quebraderos de cabeza!

3. Grandes rediseños de la web.

Habitissimo a finales del 2009

Habitissimo a inicio del 2020
Y por ello, llevamos unos meses trabajando para dejar todo eso atrás y adaptarnos a los tiempos que corren.

Mide antes de empezar….

Antes de implementar mejoras, debíamos analizar el estado actual de la web simulando una conexión 3G, y para ello debíamos apostar por las herramientas adecuadas que nos aportarán todo lo necesario para descubrir cuáles eran los mayores cuellos de botella. Optamos por dos:

1. El uso de DevTools y Lighthouse de Chrome
2. WebpageTest.org

Con ello descubrimos que unos de los mayores problemas que teníamos era el tiempo que se tomaba en parsear y ejecutar código JS

Comparación tiempo que se tomaba en cargar, parsear y ejecutar todo el código.

¿Y cómo conseguimos esas mejoras?
Con dos sencillas reglas.

  • “Doing less stuff Take Less Time”
  • “If you can do it later. Do it later”

Empezamos a simplificar para no acabar creando vistas sobrecargadas y que además, no nos estaba dando la posibilidad de ofrecer una buena experiencia de usuario.

Analizar el tiempo de ejecución de JS para cargar código bajo demanda o de manera asíncrona para no provocar bloqueo de renderizado.

Soluciones.

Empezamos a dividir nuestro código en pequeños módulos que se iban a ir cargando según en la vista que te encuentres o si el usuario ha interactuado con la web. ¿Por qué cargar y ejecutar un script en la primera carga de la web si ésta tan sólo es necesario cuando el usuario llega a X elemento?

Para darle compatibilidad a ES6 con ES5 y a la vez que sea factible el uso de dicha función en PHP a través del tag script hemos tenido que implementar la funcionalidad que nos permite hacer dicha carga asíncrona. La función básica consiste en crear una promise que se resuelve en el evento onload del script o, si ha habido un error, que realice el reject con el motivo del error.

En los casos donde necesitamos que cargue un script con eventos, ya sea scroll o click o cualquier otro evento.

Al utilizar la función podríamos hacerlo de la siguiente manera:

importScript(‘./my.js’, [‘click’, ‘scroll’])

Aparte de aplicar un code splitting, hemos eliminado varias librerías que daban soporte a navegadores deprecados o de eliminar otras (como lazy load) a implementar dicha funcionalidad puramente Vanilla JS y nuevas funcionalidades del navegador.

Por otra parte, en el proceso de compilar el javascript, hemos eliminado UglifyJS a favor de TerserJS la cual ha disminuido en ~10kb el peso de nuestros archivos JS en producción.

Aplicamos Lazy load de imágenes usando Intersection observer permitiéndonos así prescindir de blazy (un plugin desactualizado desde hace más de 2 años) disminuyendo así el peso de nuestro archivos JS.

Carga asíncrona de fuentes. Detectamos que con las fuentes sufríamos bastante de FOUT (Flash of Unstyled Text), por tanto, si el usuario visita por primera vez nuestra página web las fuentes son cargadas de manera asíncrona a través de JavaScript, por ello establecemos Arial como fuente inicial de la web, en cambio, si el usuario ya había visitado la web, las fuentes son cargadas por los estilos (font-face).

Antes y después de establecer Arial como fuente por defecto en la primera carga


Además hemos añadido la Compresión Brotli, una técnica de compresión que ofrece hasta una reducción del 30% en la transferencia de los archivos estáticos comparado con gzip.

Tras aplicar estos cambios, los resultados que obtuvimos fueron un aumento en el rendimiento (Performance) y en el tiempo de Interactividad (TTI).

Performance según Lighthouse aumentó ~90%
Time to interactive según Lighthouse disminuyó ~30%

Aún nos queda trabajo por hacer ya que tan sólo nos hemos enfrentado a una pequeña parte de nuestro problema (JS), y nos queda simplificar nuestros estilos (CSS). De momento lo que hemos hecho es separar los estilos de la guía de precios para que tan sólo cargue lo necesario en esa vista, queda pendiente realizar un análisis profundo de toda la web y eliminar lo innecesario.

Conclusión

Si bien aún seguimos con un proceso de mejora, esta primera iteración nos permitió descubrir oportunidades para mejorar tanto nuestro TTI (Time to Interactive) como el tiempo de desarrollo además de concienciarnos en aplicar buenas prácticas, para ello le damos un mayor peso a nuestra nueva guía de estilos.

  •  
  •  
  •  
  •  
  •  

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.