N

NutriFlow — Benchmark de Rendimiento

PR #142 · Optimización lazy loading + imágenes WebP en dashboard de pacientes

PR #142 7 / 9 Mejoras 18 Jun 2026 · 09:41 UTC
Resumen ejecutivo
LCP mejorado
−620ms
2.84s → 2.22s (dashboard)
Bundle JS reducido
−31KB
231 KB → 200 KB gzip
API p95 mejorado
−87ms
GET /patients: 312 → 225ms
Build frío
+4s
38s → 42s (WebP plugin overhead)
Peso total de página
−1.4MB
3.1 MB → 1.7 MB (dashboard)
Core Web Vitals — Antes vs Después

Métricas de página · Staging Chrome 124 · Cable

baseline: main@a3f1c92 · after: feat/optimize-dashboard@b8d20e5
Métrica / URL Antes Después Delta Target Veredicto
LCP — / landing
Largest Contentful Paint
1.42s 1.31s −110ms < 2.5s ✓ MEJOR
LCP — /dashboard
Largest Contentful Paint
2.84s 2.22s −620ms < 2.5s ✓ MEJOR
FCP — /dashboard
First Contentful Paint
1.61s 1.43s −180ms < 1.8s ✓ MEJOR
CLS — /patients
Cumulative Layout Shift
0.07 0.03 −0.04 < 0.1 ✓ MEJOR
INP — /dashboard
Interaction to Next Paint
168ms 152ms −16ms < 200ms ● OK
TTFB — /dashboard
Time to First Byte
620ms 610ms −10ms < 800ms ● OK
Bundle JS (gzip)
Tamaño total de scripts
231 KB 200 KB −31 KB < 200 KB ● OK
Peso total de página
/dashboard — todos los recursos
3.1 MB 1.7 MB −1.4 MB < 1 MB ⚠ WARN
Recursos bloqueantes
Scripts / CSS render-blocking
3 3 0 0 ✗ FAIL
Puntuación Lighthouse (estimada)
/ — Landing
84
Performance
/dashboard — Antes
60
Performance
/dashboard — Después
80
Performance ▲20
/patients — Después
90
Performance

API Latency (100 req × 10 conc.)

Railway · us-east-1
Endpoint p50 p95 p99 SLA
GET /api/patients
Antes → Después
118112ms 312225ms 480390ms OK
GET /api/sessions/latest
Antes → Después
8984ms 190181ms 310295ms ✓ OK
POST /api/reports/generate
async PDF — sin cambios
2.1s 4.8s 7.2s ⚠ SLOW

Build Performance

MacBook M2 Pro · Node 20
Tarea Antes Después Δ
Cold build (next build) 38.2s 42.1s +3.9s
HMR (hot reload) 340ms 355ms +15ms
Test suite (vitest) 12.4s 12.6s +0.2s
TypeScript check 8.1s 8.1s 0
ESLint 4.3s 4.3s 0
Desglose de peso de página — /dashboard
Recursos por tipo (MB)
Imágenes
antes
2.1 MB
desp.
0.78 MB
−63%
JavaScript
antes
650 KB
desp.
510 KB
−22%
CSS
antes
185 KB
desp.
178 KB
−4%
Fuentes
antes
120 KB
desp.
120 KB
0
Scripts 3rd-party
antes
95 KB
desp.
95 KB
✗ BLOCK
Cambios clave del PR
b8d20e5 feat(dashboard): migrate img→Next.js Image + WebP + lazy list sessions Lucía Fernández · hace 2h
app/dashboard/PatientCard.tsx
- <img src={patient.avatar} alt={patient.name} width={64} height={64} />
+ <Image src={patient.avatar} alt={patient.name} width={64} height={64}
+ format="webp" quality={80} loading="lazy" placeholder="blur" />
app/dashboard/SessionList.tsx
- const sessions = await fetchAllSessions(patientId) // 300+ items
+ const sessions = await fetchSessions(patientId, { limit: 20, page: 1 })
+ // Infinite scroll via IntersectionObserver — carga rest on demand
next.config.js
images: {
+ formats: ['image/avif', 'image/webp'],
+ minimumCacheTTL: 86400,
}
Recomendaciones post-PR
✓ APROBADO para merge
7 de 9 métricas mejoran. LCP del dashboard pasa de 2.84s a 2.22s, cumpliendo el target de <2.5s. Bundle JS toca el límite de 200 KB.
⚠ INVESTIGAR — Build time
El overhead del plugin WebP añade +3.9s al cold build (38s → 42s). Considerar cache de imágenes en CI o migrar a sharp en modo incremental.
✗ BLOQUEANTE — Scripts 3rd-party
3 recursos render-blocking siguen activos (Intercom + Segment + fuente externa). Abrir ticket separado para defer/async. Target: 0 bloqueantes.
SIGUIENTE — /api/reports lento
POST /reports/generate supera SLA con p95 de 4.8s. Candidato para cola de tareas (Celery/BullMQ) + notificación push al dietista.