# Auditoria Performance

> Auditoria de velocidad y eficiencia de tu app, full-stack. Mide Core Web Vitals (LCP, INP, CLS) en desktop y movil con red simulada, peso del bundle y assets, queries SQL lentas, tiempo de respuesta de las APIs, fugas de memoria tras sesion prolongada, y queries N+1 en listados. Detecta lo que erosiona la experiencia del usuario sin romper nada visualmente. Activar cuando el usuario dice: auditoria de performance, mi app va lenta, audita el rendimiento, /auditoria-performance. OBLIGATORIA antes de un lanzamiento publico o entrega a un cliente.

- Skill: `lalakinskywalker/auditoria-performance` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lalakinskywalker/auditoria-performance`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lalakinskywalker/auditoria-performance/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: LalakinSkywalker (https://skillmd.com/u/lalakinskywalker)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/lalakinskywalker/auditoria-performance

---


# Auditoría de performance — ¿Tu app es ágil o desespera?

> Una app puede funcionar perfecto, respetar la configuración y verse impecable, y aun así perder usuarios porque tarda 5 segundos en cargar o se traba al hacer clic. Esos bugs no rompen nada visiblemente — solo erosionan la experiencia. Esta skill los mide y los arregla.

---

## Las 6 dimensiones (cada una con sus umbrales 🟢🟡🔴)

### D1 — Core Web Vitals (escritorio + móvil con red 3G simulada)
Las 3 métricas oficiales de Google, medidas con Lighthouse vía Playwright, en el mejor caso (escritorio con fibra) y el peor caso realista (móvil 3G):

| Métrica | Qué mide | 🟢 | 🟡 | 🔴 |
|---|---|---|---|---|
| **LCP** | Cuándo aparece el contenido principal | <2.5s | 2.5-4s | >4s |
| **INP** | Qué tan rápido responde a los clics | <200ms | 200-500ms | >500ms |
| **CLS** | Que el layout no salte al cargar | <0.1 | 0.1-0.25 | >0.25 |
| Score Lighthouse | Global | ≥90 | 70-89 | <70 |

### D2 — Peso del bundle y los assets

| Asset | 🟢 | 🟡 | 🔴 |
|---|---|---|---|
| JS de carga inicial | <300KB | 300-500KB | >500KB |
| JS por ruta | <100KB | 100-200KB | >200KB |
| Imagen hero | <200KB | 200-500KB | >500KB |
| Total descargado (home) | <1MB | 1-2MB | >2MB |
| Fuentes web | 1-2 | 3-4 | >4 |

**Típicos:** "carga inicial de 850KB → falta code-splitting"; "imagen hero de 2MB → convertir a WebP"; "librería de charts entera importada para una función → tree-shaking".

### D3 — Queries SQL lentas
Con `pg_stat_statements`: resetear stats → navegar la app a fondo → leer las queries más lentas.

| Métrica | 🟢 | 🟡 | 🔴 |
|---|---|---|---|
| Tiempo medio por query | <100ms | 100-500ms | >500ms |
| Tiempo máximo | <1s | 1-3s | >3s |
| Sequential scans en tablas grandes (>10k filas) | 0 | 1-2 | >2 |

**Típico:** "el listado ordenado por fecha tarda 2.3s → falta índice en `(cliente_id, created_at)`".

### D4 — Tiempo de respuesta de las APIs
Capturar el Network durante la navegación, calcular p50 y p95 por endpoint.

| Métrica | 🟢 | 🟡 | 🔴 |
|---|---|---|---|
| Endpoint p50 | <200ms | 200-500ms | >500ms |
| Endpoint p95 | <500ms | 500-1500ms | >1.5s |
| TTFB inicial | <600ms | 600-1500ms | >1.5s |

**Típico:** "la acción hace 3 queries secuenciales que podrían ir en paralelo con `Promise.all`".

### D5 — Fugas de memoria (sesión prolongada)
Medir la memoria base, navegar 15-30 min haciendo flujos repetitivos (abrir/cerrar modales, cambiar filtros, ir y volver entre páginas), medir la memoria final.

| Crecimiento tras 15 min | 🟢 | 🟡 | 🔴 |
|---|---|---|---|
| memoria final / inicial | <1.5x | 1.5-3x | >3x |

**Típico:** "la memoria creció de 45MB a 380MB → un componente no limpia sus event listeners (useEffect sin cleanup)"; "el stream del agente mantiene el EventSource abierto tras cerrar el chat".

### D6 — Queries N+1
Resetear stats → cargar un listado → contar las queries. Si el número crece con la cantidad de items, es N+1.

| Listado de N items | Queries esperadas | Bug si… |
|---|---|---|
| Simple, sin relaciones | 1-2 | >5 |
| Con 1 relación | 2-3 | >N/2 |
| Con 2-3 relaciones | 3-5 | proporcional a N |

**Típico:** "un listado de 50 items dispara 51 queries → falta un JOIN".

---

## El flujo

1. **Detectar el alcance** (app completa o lo que el usuario indique).
2. **Medir las 6 dimensiones** con navegador real + Lighthouse + queries a la base. Cada hallazgo lleva su semáforo.
3. **Loop medir-arreglar-remedir:** atacar primero los 🔴, luego los 🟡 baratos. Cada fix se re-mide para confirmar la mejora (no solo "debería ser más rápido" — comprobarlo).
4. **Pausar y preguntar** si la mejora exige un cambio de arquitectura mayor (migrar un proceso pesado fuera de serverless, rediseñar el modelo de datos).
5. **Limpieza:** stats reseteadas, registros de prueba borrados, base idéntica al estado previo.
6. **Reporte semáforo + autorización.** El push/deploy lo autoriza el dueño.

---

## Reglas duras

1. **Medir, no suponer.** Cada hallazgo viene de una medición real (Lighthouse, `pg_stat_statements`, Network), no de "esto se ve pesado".
2. **Re-medir tras cada fix** para confirmar la mejora con números.
3. **Atacar 🔴 primero**, luego 🟡 baratos; 🟢 se deja.
4. **Pausar por cambio de arquitectura mayor**, no por dificultad.
5. **El push/deploy lo autoriza el dueño.**

---

## Anti-patrones (prohibidos)

- "Le metí caché, ya debe ir más rápido." → Re-medir y comprobar con números.
- "El build no se quejó del tamaño." → El framework no avisa; hay que leer el reporte de bundle.
- "Funciona rápido en mi máquina." → Medir en móvil 3G simulado, que es el usuario real.
- "Optimicé la query que se me ocurrió." → Optimizar la que `pg_stat_statements` señala como la más lenta, con datos.

