Optimización de Performance Web
Mejora Core Web Vitals, reduce tamaños de bundle y optimiza performance frontend con lazy loading, code splitting y herramientas de build modernas.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Visión General
El performance web impacta directamente el engagement de usuarios, tasas de conversión y rankings de búsqueda. Los Core Web Vitals de Google — Largest Contentful Paint (LCP), Interaction to Next Paint (INP) y Cumulative Layout Shift (CLS) — proveen targets medibles. Este recurso cubre técnicas prácticas: lazy loading, code splitting, optimización de imágenes, critical CSS y modern build tooling para lograr cargas de página bajo 3 segundos.
Cuándo Usar
Usa este recurso cuando:
- Los scores de Core Web Vitals están fallando (LCP > 2.5s, CLS > 0.1)
- Usuarios móviles en redes 3G abandonan páginas antes de que carguen
- Los bundle sizes exceden 200KB e impactan el time-to-interactive
- Scripts de terceros (analytics, ads) bloquean el main thread
Solución
Critical CSS Inline + Async Load (HTML)
<head>
<!-- Inline critical CSS (~14KB max) -->
<style>
/* Above-fold styles: header, hero, layout skeleton */
body{margin:0;font-family:system-ui}
.hero{background:#3b82f6;min-height:60vh}
</style>
<!-- Preload key resources -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/hero-image.webp" as="image" fetchpriority="high">
<!-- Async load non-critical CSS -->
<link rel="preload" href="/styles.css" as="style" onload="this.rel='stylesheet'">
</head>
Lazy Loading Images con API Nativa
<!-- Native lazy loading — no requiere JavaScript -->
<img src="hero.webp" alt="Hero" fetchpriority="high" width="800" height="400">
<img src="below-fold-1.webp" alt="Product" loading="lazy" width="400" height="300">
<img src="below-fold-2.webp" alt="Team" loading="lazy" width="400" height="300">
Code Splitting con Dynamic Imports (React)
import { lazy, Suspense } from 'react';
const HeavyChart = lazy(() => import('./HeavyChart'));
const AnalyticsDashboard = lazy(() => import('./AnalyticsDashboard'));
function Dashboard() {
return (
<div>
<CriticalStats /> {/* Siempre cargado */}
<Suspense fallback={<Spinner />}>
<HeavyChart /> {/* Cargado on demand */}
</Suspense>
<Suspense fallback={<Spinner />}>
<AnalyticsDashboard /> {/* Chunk separado */}
</Suspense>
</div>
);
}
Explicación
Targets de Core Web Vitals:
| Métrica | Bueno | Malo | Mide |
|---|---|---|---|
| LCP | < 2.5s | > 4s | Tiempo de carga del elemento visible más grande |
| INP | < 200ms | > 500ms | Responsividad de interacciones |
| CLS | < 0.1 | > 0.25 | Estabilidad visual (layout shifts) |
| TTFB | < 600ms | > 1.8s | Time to first byte |
Ejemplo de performance budget:
- JavaScript: 150KB (gzipped)
- Imágenes: 250KB total
- CSS: 50KB (incluyendo critical inline)
- Fonts: 40KB (subsetted)
- Terceros: 100KB máximo
Variantes
| Técnica | Impacto | Esfuerzo |
|---|---|---|
| Optimización de imágenes (WebP/AVIF) | -50% bytes de imagen | Bajo |
| Font subsetting | -80% bytes de font | Bajo |
| Code splitting | -60% JS inicial | Medio |
| Edge caching | -90% TTFB | Bajo |
| Service Worker | Visitas repetidas instantáneas | Medio |
| HTTP/3 + QUIC | Más rápido en redes con pérdida | Bajo (CDN) |
Mejores Prácticas
- Mide usuarios reales, no tests de lab: Field data de Chrome UX Report refleja condiciones actuales
- Optimiza el critical path: Cualquier cosa bloqueando
<head>debería estar bajo 50KB total. Consulta server-side rendering. - Self-host fonts y analytics: Conexiones de terceros agregan overhead de DNS + TLS + TCP
- Usa
content-visibility: auto: Los browsers skip rendering de contenido off-screen - Defer JavaScript no crítico:
deferotype="module"para scripts no necesarios inmediatamente
Errores Comunes
- Imágenes hero oversized: Un PNG hero de 4MB destruye LCP; usa imágenes responsive con
srcset - Terceros render-blocking: Google Fonts cargados síncronamente retrasan first paint
- Sin resource hints:
preload,prefetchypreconnectson wins de performance gratuitos - Hidratar todo: Arquitectura de islands (Astro, Fresh) envía zero JS para contenido estático
- Ignorar mobile: 70% de usuarios están en mobile; testea en dispositivos reales, no solo DevTools
Preguntas Frecuentes
P: ¿Cuál es la única mejora de performance más grande? R: Optimización de imágenes. Las imágenes son típicamente 60-80% del peso de página. Usa formatos modernos, sizing responsive y lazy loading.
P: ¿Debería usar un CDN? R: Sí. Un CDN reduce TTFB sirviendo desde edge locations cercanas a los usuarios. Esencial para audiencias globales.
P: ¿Cómo balanceo performance con developer experience? R: Usa frameworks que optimizan por default (Astro, SvelteKit, Next.js con App Router). No luches contra las herramientas.
Recursos Relacionados
Web Performance Optimization Guide
A comprehensive guide to optimizing web application performance for better Core Web Vitals and user experience.
RecipeSPA Performance: Code Splitting and Lazy Loading
Improve single-page application load times by splitting bundles at route and component level, implementing lazy loading with React.lazy and dynamic imports
DocCapacity Planning Template
A reusable template for planning system capacity, estimating growth, and preventing performance bottlenecks before they happen.
GuideSystem Design Interview Guide — Key Concepts
A practical guide to system design interviews: scalability, databases, caching, load balancing, microservices, and how to structure your answer.
GuideSQL Performance Tuning — Indexes, Queries, and Explain Plans
A practical guide to optimizing SQL queries: indexing strategies, query rewriting, EXPLAIN plan analysis, and common anti-patterns to avoid.