StackPractices
intermediate Por Mathias Paulenko

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.

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 Live 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étricaBuenoMaloMide
LCP< 2.5s> 4sTiempo de carga del elemento visible más grande
INP< 200ms> 500msResponsividad de interacciones
CLS< 0.1> 0.25Estabilidad visual (layout shifts)
TTFB< 600ms> 1.8sTime 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écnicaImpactoEsfuerzo
Optimización de imágenes (WebP/AVIF)-50% bytes de imagenBajo
Font subsetting-80% bytes de fontBajo
Code splitting-60% JS inicialMedio
Edge caching-90% TTFBBajo
Service WorkerVisitas repetidas instantáneasMedio
HTTP/3 + QUICMás rápido en redes con pérdidaBajo (CDN)

Lo que funciona

  • 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: defer o type="module" para scripts no necesarios inmediatamente

Errores Comunes

  1. Imágenes hero oversized: Un PNG hero de 4MB destruye LCP; usa imágenes responsive con srcset
  2. Terceros render-blocking: Google Fonts cargados síncronamente retrasan first paint
  3. Sin resource hints: preload, prefetch y preconnect son wins de performance gratuitos
  4. Hidratar todo: Arquitectura de islands (Astro, Fresh) envía zero JS para contenido estático
  5. Ignorar mobile: 70% de usuarios están en mobile; testea en dispositivos reales, no solo DevTools

Lectura Adicional

  • Documentación oficial: consulta la referencia actualizada del framework o herramienta utilizada.
  • Guías relacionadas: explora las guías de web-performance y performance para profundizar.
  • Patrones complementarios: revisa los patrones de diseño aplicables a tu stack tecnológico.
  • Postmortems públicos: estudia incidentes reales de equipos que enfrentaron problemas similares en producción.

Notas de Producción

  • Despliega gradualmente usando canary o blue-green para detectar regresiones temprano.
  • Configura alertas para errores, latencia p99 y tasa de fallos antes de habilitar en producción.
  • Documenta el rollback en el runbook; prueba el procedimiento en staging al menos una vez por trimestre.
  • Revisa logs estructurados con correlation IDs para trazar requests end-to-end en incidentes.

Puntos Clave

  • Aplica optimización de performance web cuando necesites una solución práctica para tu caso de uso.
  • Monitorea el rendimiento después de implementar; mide latencia, errores y uso de recursos antes y después.
  • Revisa la sección de Troubleshooting ante errores comunes; la mayoría tienen causa raíz documentada con solución.
  • Mantén dependencias actualizadas y ejecuta tests en CI para prevenir regresiones en producción.

Ver También


Última actualización: 2026-07-09

Troubleshooting

  • Largest Contentful Paint is high: optimize images, preload critical resources, and reduce server response time.
  • JavaScript bundle size grows: analyze the bundle, split code by route, and tree-shake unused dependencies. Lazy-load non-critical components.
  • Cache hit rate is low: review cache keys, TTLs, and invalidation patterns.
  • Database CPU spikes: find the top queries by execution time and frequency. Add indexes, rewrite queries, or cache results.
  • Throughput drops under load: profile for contention, garbage collection, and blocked threads. Scale horizontally only after optimizing the hot path.

Errores Comunes en Producción

  • Copiar el ejemplo sin adaptarlo a volúmenes y modos de fallo reales.
  • Saltar tests de carga e inyección de errores antes del primer despliegue productivo.
  • Codificar valores fijos que deberían ser configurables por entorno.
  • Olvidar agregar logging y monitoreo en cada paso.
  • Desplegar sin plan de rollback ni estrategia de backup probada.
  • Asumir que el ejemplo mínimo escalará sin agregar caché o procesamiento por lotes.
  • No documentar la versión y configuración usadas en producción.
  • Dejar la receta sin cambios cuando evolucionan las dependencias o la escala.

Preguntas frecuentes

¿Cuál es la única mejora de performance más grande?

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.

¿Debería usar un CDN?

Sí. Un CDN reduce TTFB sirviendo desde edge locations cercanas a los usuarios. Esencial para audiencias globales.

¿Cómo balanceo performance con developer experience?

Usa frameworks que optimizan por default (Astro, SvelteKit, Next.js con App Router). No luches contra las herramientas.