Camino a ser experto en web performance - Performance budgets
Tags: webdev, webperf, performance
Published: 2024-03-25 03:36:44

En un post anterior hablamos sobre la [cultura del performance](https://dev.to/dezkareid/camino-a-ser-experto-en-web-performance-cultura-del-performance-46md), esta es la continuación donde hablaremos de como esa cultura se convierte performance budgtes.

![Meme: ahora si se viene lo chido](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h63lwa832wua1lwacc3t.png)

## Performance budgets
Los performance budgets son presupuestos que tenemos para que nuestra web pueda operar. Exacto, PRESUPUESTOS; como en las finanzas personales (al menos las sanas) uno establece presupuestos al hacer compras como televisiones, autos, despensa (comida del mes), salidas por la noche, figuritas y coleccionismo (no tengo finanzas sanas con las figuritas XD).

> Budget hace alusión a presupuesto pero en la realidad puede ser manejado como un contrato, límite o incluso como una meta. 

Como todo presupuesto, puede crecer o reducir dependiendo de lo que se necesite y no se acumula (eso es ahorro). En el desarrollo web del día a día esto no nos preocupa para nada, lo mas cercano a presupuesto que nos preocupa es la cuenta de nuestro proveedor de la nube.

![Meme: ya muestranos los performance budgets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ozqvlaso25q84nz4tmo5.png)

¿Cómo defino estos performance budgets? Bueno, a diferencia de nuestras finanzas personales estas son un poco mas complejas (creo). Debido a que los performance budgets involucran una serie de métricas que están relacionadas con todo aquello que afecta nuestra web (y pueden chocar entre si). Estas métricas están agrupadas en 3 grupos:

- Milestone timings ⏱️
- Quantity-based metrics ⚖️
- Rule-based metrics 💯

### Milestone timings ⏱️
Métricas definidas por eventos en el browser (como [DOMContentLoaded](https://developer.mozilla.org/docs/Web/Events/DOMContentLoaded)). Todas estás métricas tienen como base intervalos de tiempo

Estas pueden medirse usando directamente desde la API del browser. Pueden ser una combinación de varios eventos o pueden ser eventos que involucren alguna interacción con el usuario y que tán rápido este obtiene una respuesta a esa interacción.

Un ejemplo son las [metricas centradas en el usuario] (https://web.dev/articles/user-centric-performance-metrics) o [core web vitals](https://web.dev/articles/vitals#core-web-vitals).

Es un tema bastante extenso que aborademos en otros posts

### Quantity-based ⚖️
Métricas definidas por el tamaño o cantidad de los assets/recursos que usas en tu web. Cuando se trata de tamaño normalmente usamos kilobytes o megabytes.

Todo aquello que afecta a la carga de tu web: Documents, estilos externos, imágenes, scripts y bibliotecas de terceros.

Es un tema bastante extenso que aborademos en otros posts

### Rule-based 💯
Métricas definidas por herramientas de auditoria como [lighthouse](https://developer.chrome.com/docs/lighthouse/overview).

> Lighthouse puede auditar varios aspectos de una aplicación como accesibilidad pero nos enfocaremos en performance 

Usando como ejemplo lighthouse, una de sus métricas se llama [performance score](https://developer.chrome.com/docs/lighthouse/performance/performance-scoring#metric-scores). Esta se define por un conjunto de buenas prácticas definidas en la industria y su estado actual. Revisa esta tool llamada [Lighthouse Scoring Calculator](https://googlechrome.github.io/lighthouse/scorecalc/) para que conozcas mas acerca de esto)

Ya se la saben, tema extenso. Se va para mi backlog de posts

![Meme: Lo repites tanto que ya ha perdodo su significado](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pk7irgmdt1hfp5qgvcbg.png)

### De un objetivos a performance budgets
En posts anteriores hablamos sobre que debemos estar alineados por ciertos objetivos que todo el equipo entienda. Estos objetivos serán la base de nuestros budgets.

> Nuestra página principal debe cargar en 2.5 segundos o menos, en dispositivos móviles de gama media con una conexión 3G normal

De este objetivo podemos definir algunos budgets

En métricas Milestone timings podemos definir el siguiente budget:
* El [Largest ContentFul Paint](https://web.dev/articles/lcp)(LCP) de la página principal debe ser menor de 2.5 segundos
* [El First ContentFul Paint](https://web.dev/articles/fcp)(FCP) de la página debe ser menor a 2s 

En métricas Quantity-based es un poco mas complejo ya que debemos tomar en cuenta la velocidad de la red ya que eso nos dice cuanta información se puede transmitir. Esa sería nuestra base para el budget

Tomando en cuenta que una conexión 3g normal, le descarga es de descarga 780kilobits por segundo, en 2.5 segundo podemos descargar tenemos 1950 kilobits, esto expresado en kilobytes serían un poco mas de 240kb (243.75)

> Por ende la suma de todos tus assets no debe pasar de este peso o ninguno de tus assets debería pesar mas de lo que puedes transferir (puede haber excepciones)

Y a partir de eso podemos definir los budgets para cada uno de los assets que ocupamos en nuestra página. En este caso vamos a usar [performancebudget.io](https://www.performancebudget.io/) para empezar a hacer ese budget.

1. Selecciona en tipo de metricas assets
2. Selecciona la velocidad de conexión (3G Slow de 780kb)
3. Escribe la velocidad en segundos(2.5)
4. Modifica los valores que se adapten a lo que necesites

En esta parte del proceso tendremos algo similar a esto

![Selección del tamaño de los assets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/704r5ajnh3g2oir2dz4v.png)

5. En el siguiente paso se nos muestra un resumen de nuestro budget

![Performance budget](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c0ct5fm28w3gczce57xt.png)

Ademas del tiempo de descarga estimada para otras velocidades de red

![Tabla de velocidades del performance budget](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x63rtu615ms4js862ush.png)

6. Finalmente puedes descargarlo en un formato que es compatible con lighthouse-ci (explicaré esto en un post dedicado a auditorias)

```json
[
  {
    "resourceSizes": [
      {
        "resourceType": "document",
        "budget": 6
      },
      {
        "resourceType": "stylesheet",
        "budget": 7.8
      },
      {
        "resourceType": "script",
        "budget": 39.6
      },
      {
        "resourceType": "image",
        "budget": 151.2
      },
      {
        "resourceType": "media",
        "budget": 23.4
      },
      {
        "resourceType": "font",
        "budget": 12
      }
    ],
    "timings": []
  }
]
```
En un lenguaje mas humano podemos decir que:
* La página principal debe cargar 6kb de html o menos
* La página principal debe cargar 7.8kb de css o menos
* La página principal debe cargar 39.6kb de JS o menos
* La página principal debe cargar 151.2kb de imagenes o menos
* La página principal debe cargar 23.4kb de recursos multimedia o menos
* La página principal debe cargar 12kb de fuentes o menos

Listo ya tenemos nuestros budgets en terminos de Quantity-based

En métricas Rule-based podemos ir a [lighthouse scoring calculator](https://googlechrome.github.io/lighthouse/scorecalc/) y definir nuestro budget, seleccionando la versión de Lighthouse (10) y el tipo de target (mobile). En este caso nuestro budget es una combinación de métricas (algunas que definimos ya en milestone timings)

Al agregar el límite máximo de nuestros budgets a lighthouse podemos ver el score aproximado que deberiamos de tener, en este caso: 93.

![Lighthouse score calculator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t6aatsz8x81pycnuo68e.png)

Y finalmente con todo esto podemos tener nuestro budget:

* El score en performance de la página principal debe ser al menos de 93% en lighthouse

Este es un ejemplo de budget que podría ser visto como una meta que fija un límite para ir hacia adelante.

## Dificultad al definir budgets
Una de las partes complejas de crear budgets es entender que estos pueden estar relacionados y el modificar uno puede presentar un side-effect en otro.

Ejemplo el FCP y el LCP, si tu HTML y CSS que necesitas para renderizar tu aplicación sobrepasan 240kb y tu budget es para conexión 3G vas a tener problemas.

Si tus métricas tienen que ver con [TTI](https://web.dev/articles/tti), [INP](https://web.dev/articles/inp) o [FID](https://web.dev/articles/fid) pero tienes un uso excesivo de JS, tendrás problemas.

Es por ello que los performance budgets deben partir de objetivos alineados a tu negocio donde el foco este en la experiencia de los usuarios que te generen mejor revenue, tomando en cuenta las condiciones de estos como base.

Puedes optimizar para conexiones 3G y los usuarios con 4G tendrán un sitio más rápido. Si la experiencia es buena en conexiones lentas, podría ser mejor para conexiones rápidas o no? No necesariamente

![Meme: Por un demonio lo que faltaba](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h9nugxf3qhhuq9rt6h38.png)

Si bien la rápidez es parte clave del performance, no solo se necesita ser rápido sino también usable. Podríamos hacer que un sitio web cumpla con todas las métricas que estableciamos agregando delay de recursos, reduces el tiempo de carga pero podrías aumentar el tiempo en que al usuario le toma hacer lo que necesita.

Es importante recordar que no todas las métricas de una web deben tener un budget solo las significativas para tu negocio.

> También hay algunos performance budgets que se establecen en base a lo que tu competencia tiene (ya se la saben XD)

## Siguientes pasos
Una vez que ya definimos nuestros budgets (no necesariamente se hace en este orden). Lo que sigue es usarlos para auditar nuestras aplicaciones. Eso queda fuera del scope de este post pero voy a dar un adelanto.

![Meme: It's something (ya es algo)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dm344hojup68c59y1wpk.png)

Así como la pirámide del tests hay auditorias de performance que se realizarán dependiendo del ambiente(stage) de la aplicación. Para obtener feedback lo más rápido posible sin tener que llegar al stage de producción.

> Un budget es una descripción que nos guía a una implementación

Hay algunos bundlers como webpack que tiene ciertas [configuraciones de performance](https://webpack.js.org/configuration/performance/) pueden servirnos en ambiente local para cuidar el tamaño de cierto tipo de assets.

[Bundlesize](https://github.com/siddharthkp/bundlesize) es una tool que nos puede ayudar en CI como gatekeeper para cuidar que nuestros performance budgets de tipo Quantity se cumplan.

[Lighthouse-ci](https://github.com/GoogleChrome/lighthouse-ci) nos puede ayudar para realizar auditorias de performance budget de tipo rule-based pero también de milestone timings y quantity. En un ambiente CI pero también en ambientes de Quality Assurance.

Y un overview de herramientas más robustas como [webpagetest](https://www.webpagetest.org/), [calibre](https://calibreapp.com/), [speedcurve](https://www.speedcurve.com/), entre otras. Espero les haya gustado, de ser así compartan, comenten y reaccionen, no va a pasar nada si no lo hacen pero sería genial :D