¿Cómo medimos qué pasa del lado del cliente en Despegar?
CSPERF, nuestra solución para entender lo que pasa client-side.
Un poco de contexto sobre nuestra problemática
En Despegar tenemos un amplio stack de aplicaciones frontend divididas en diversas gerencias (Shopping, Aftersale, Payments) y construidas con distintas tecnologías como pueden ser: React, Angular,jQuery, Vanilla JS, entre otras.
En este contexto nos planteamos cómo hacer para medir la performance de una manera que nos sea representativa, universal y tenga los menores desvíos posibles para que sea confiable y comparable a lo largo del tiempo.
La forma tradicional de hacerlo, y que hacen muchas aplicaciones como por ejemplo Newrelic, Lighthouse, PageSpeed entre otras es analizar los valores que se registran en la API performance del navegador, brindando datos relativos de la performance en ese contexto de ejecución.
El problema de estas métricas relativas es que dependen en gran parte del contexto de ejecución y están afectadas por todos los demás recursos que se cargan en la misma aplicación.
El contexto de ejecución está dado por la combinación de CPU + RED.
Una aplicación frontend con una conexión de 300Mb y un Chrome corriendo en una Dell con un Intel i7 no va a performar igual que esa misma aplicacion corriendo en el celular de gama baja con una conexion 3G y un procesador prácticamente de juguete.
Como si esto fuera poco, tenemos que considerar que en toda aplicación frontend se cargan recursos externos a esta app pero necesarios como por ejemplo: herramientas de trackeos, componentes, dependencias de estos componentes, pixeles de marketing, entre otros.
Aquello que no se puede medir, no existe y no se puede comparar en el tiempo.
Frente a este escenario complejo surge la necesidad de saber cómo se comporta nuestra aplicación en los navegadores de nuestros clientes, producto de esto se desprende otro requerimiento fundamental: poder determinar si las mejoras de performance tienen impacto o estamos gastando pólvora en chimango.
CSPERF, nuestra solución a esa problemática
Para poder medir qué pasa del lado del cliente, tanto de manera absoluta como relativa, creamos una aplicación a la cual llamamos “CSPERF”. Esta aplicación construida en Node y Javascript Vanilla nos permite recolectar todos los datos que se guardan en el objeto performance del navegador brindándonos la posibilidad de procesar esa información como nosotros querramos.
Hablamos de valores absolutos en casos donde estos no dependen del contexto como por ejemplo: el tamaño de un archivo CSS, la cantidad de dependencias externas, cuántos kilobytes de dependencias sobre el total tenemos, etc.
Gracias a esta aplicación y el procesamiento de todos estos valores, creamos una marca custom a la cual denominamos “main_feature” que representa lo siguiente:
El momento, desde la carga inicial de la página en que nuestra funcionalidad principal está disponible y operable por el cliente.
Y en nuestra aplicación se visualiza de la siguiente manera:
Para, para, para.. En español.. Vamos a los ejemplos para que quede clara esta idea de “main_feature”:
- En un checkout, el main_feature es cuando el botón comprar está clickleable.
- En una búsqueda, cuando se dibujó el primer resultado de búsqueda.
- En la home o una landing, cuando la caja de búsqueda está operable.
Esta métrica, si bien depende del contexto de ejecución nos permite poder tener un dato concreto con el menor desvío posible acerca de cuándo el cliente puede usar nuestra funcionalidad principal en un determinado flujo.
En una línea de tiempo el main_feature se vería algo así:
Como podemos observar, el main_feature [Primer recuadro rojo] se ubica por delante del FP (FIrst Paint), FCP (First Contentful Paint), LCP (Largest Contentful Paint) [Recuadros verdes de la línea de tiempo] y DOMContentLoaded Event [Recuadro Azul], pero aproximadamente 700ms antes del Onload Event [Segundo recuadro rojo]
Para materializar esto, utilizamos la performance.mark() del navegador para crear una marca que luego al cerrar la pestaña, todo el objeto performance serializado es enviado a CSPERF, procesado y representado en gráficos fácilamente legibles y comparables.
Tener este instante nos permite calcular cientos de métricas asociadas y de vital importancia, como por ejemplo:
- ¿Cuántos recursos estamos cargando antes y despues del “main_feature”?
- ¿Cuánto tiempo antes del “main_feature” estamos lanzando nuestro request AJAX principal?
- ¿Cómo evolucionó el “main_feature” mes actual con respecto al mes anterior?
- ¿Qué recursos estamos cargando antes del “main_feature”?
Gran parte de las mejoras que luego se implementan en las aplicaciones parten de contestar estos interrogantes, y para poder hacerlo necesitamos la mayor cantidad de datos posibles.
Para tener una noción, CSPERF procesa cerca de 1.200.000 métricas por minuto, llegando en eventos de industria a alcanzar cómodamente picos de 2.500.000 métricas por minuto.
En fin, es importante tener métricas históricas de la performance de una aplicación lo más reales posibles para poder medir el impacto de las mejoras o cómo evoluciona nuestra aplicación a lo largo del tiempo.
Por lo general, una métrica específica creada por nosotros nos brindara datos mas útiles que las proporcionadas nativamente por el navegador.