wandres.dev
ONTOLOGÍA · El mapa del rendimiento web

El mapa de remedios

El catálogo completo de técnicas de rendimiento web organizado por la causa que ataca cada una, con su efecto esperado y su coste de implantación.

⏱ 18 min

Existen unas cuarenta técnicas de optimización de rendimiento web con nombre propio, y casi toda la literatura las presenta como una lista de buenas prácticas que hay que aplicar todas. Eso es un error de método: cada técnica ataca una causa concreta, y aplicada donde no toca es esfuerzo perdido o directamente una regresión. Este es el mapa completo, ordenado por causa, con el efecto que cabe esperar de cada una.

🎯 Al terminar esta lección sabrás
  • Emparejar cada familia de técnicas con la causa de lentitud que ataca.
  • Estimar el orden de magnitud del efecto de cada familia antes de implementarla.
  • Descartar por adelantado las técnicas que no aplican a un problema dado.
  • Reconocer las cuatro técnicas que empeoran el rendimiento cuando se aplican mal.

Remedios por causa

El mapa se organiza en cinco columnas de causa. Cada columna tiene sus remedios y ninguno cruza de columna.

Causa 1: demasiados viajes de ida y vuelta. El tiempo se va en abrir conexiones y en esperar respuestas, no en transferir. Los remedios son reducir el número de orígenes distintos, servir desde un punto de presencia cercano al usuario, evitar redirecciones, reutilizar conexiones, y adelantar la apertura de las que sean inevitables con preconnect. HTTP/2 y HTTP/3 ayudan porque multiplexan sobre una conexión única. Efecto típico: de 100 ms a más de un segundo, según cuántos orígenes se eliminen.

Causa 2: demasiados bytes en la ruta crítica. El tiempo se va transfiriendo. Los remedios son comprimir con Brotli o Zstandard, elegir formatos de imagen modernos, servir el tamaño correcto de imagen, eliminar CSS y JavaScript no usados, dividir el bundle por rutas, y cachear agresivamente lo que no cambia. Efecto: proporcional a los bytes eliminados dividido por el ancho de banda, así que se nota mucho más en redes lentas.

Causa 3: bloqueo del renderizado. Los bytes están, pero el navegador no puede pintar. Los remedios son extraer el CSS crítico, cargar el resto de forma no bloqueante, poner defer o async en los scripts, sacarlos del head, e inlinear lo mínimo imprescindible. Efecto: mueve el FCP y, con él, el suelo del LCP.

Causa 4: el hilo principal saturado. El navegador está ocupado y no atiende. Los remedios son enviar menos JavaScript, dividir las tareas largas, ceder el hilo con las APIs del planificador, mover cómputo a un Web Worker, evitar el layout thrashing, y reducir el tamaño del DOM. Efecto: el INP baja de forma casi lineal con la duración de la tarea más larga que se solapa con la interacción.

Causa 5: layout no reservado. El contenido llega y empuja lo que ya estaba. Los remedios son declarar width y height en imágenes y vídeos, usar aspect-ratio, reservar espacio para contenido dinámico, elegir bien font-display y ajustar los descriptores de la fuente de respaldo. Efecto: el CLS puede pasar de 0,4 a 0 con un puñado de líneas de CSS.

💡
La pregunta que ordena la lista de tareas

Antes de meter una técnica en el backlog, respóndete: ¿qué número concreto espero que se mueva, y en qué dirección? Si no puedes nombrar la métrica y estimar la magnitud, no tienes una tarea de rendimiento, tienes una superstición. “Migrar a HTTP/3” no es una tarea; “reducir el TTFB del p75 en móvil de 900 a 600 ms eliminando la redirección de www” sí lo es.

La tabla de coste y efecto

No todas las técnicas cuestan lo mismo ni rinden lo mismo. Esta tabla es una guía de priorización razonable para un sitio que no ha hecho nunca trabajo de rendimiento.

Técnica Causa que ataca Efecto típico Coste de implantación
Comprimir texto con Brotli 2 15-25% menos bytes que gzip Muy bajo, configuración
Cachear estáticos con hash en el nombre 1 y 2 Elimina la red en visitas repetidas Bajo, si el build ya versiona
Declarar dimensiones de imagen 5 CLS a casi cero Muy bajo
Convertir imágenes a AVIF o WebP 2 30-60% menos bytes de imagen Bajo con herramientas
Quitar redirecciones de entrada 1 100-500 ms de TTFB Bajo, configuración
defer en todos los scripts del head 3 Adelanta el FCP cientos de ms Bajo, con cuidado del orden
Servir desde una CDN 1 Reduce el RTT según la geografía Medio
Extraer CSS crítico 3 Adelanta el FCP Medio-alto, mantenimiento delicado
Dividir el bundle por rutas 2 y 4 Menos JavaScript inicial Medio, cambia la arquitectura
Mover cómputo a un Worker 4 El INP baja mucho si el cuello era ahí Alto
Cambiar de estrategia de renderizado 3 y 4 Grande, en ambas direcciones Muy alto

El patrón que emerge es constante en todos los proyectos: los remedios de configuración rinden más por unidad de esfuerzo que los de arquitectura, y suelen estar sin hacer. Antes de plantear una migración a otro framework, comprueba que la compresión está activada, que la caché está bien configurada y que no hay tres redirecciones en la entrada. Es aburrido y funciona.

Las cuatro técnicas que hacen daño mal aplicadas

Hay cuatro optimizaciones que aparecen en todas las listas de buenas prácticas y que, aplicadas sin criterio, empeoran el rendimiento. Merecen un aviso desde el nivel cero.

preload de más. Un preload sube la prioridad de un recurso y le quita ancho de banda a los demás. Si precargas cinco cosas, has declarado que las cinco son críticas, lo cual equivale a no priorizar nada, y además compiten con el recurso que de verdad importa. Un preload equivocado es una regresión con aspecto de optimización, y el nivel 10 está dedicado en buena parte a esto.

loading="lazy" en la imagen del hero. La carga diferida de imágenes es excelente para lo que está por debajo del pliegue, y catastrófica para lo que está arriba: obliga al navegador a esperar al layout para confirmar que la imagen es visible antes de empezar a descargarla. Si esa imagen es el elemento LCP, acabas de añadir cientos de milisegundos.

Inlinear demasiado. Meter el CSS o un script dentro del HTML elimina una petición, pero también elimina la posibilidad de cachearlo por separado: cada visita paga esos bytes otra vez, y engordan el documento, que es lo que más importa que llegue rápido. Inlinear tiene sentido para unos pocos kilobytes de CSS crítico, no para una hoja de estilos entera.

Dividir el bundle sin medir. El code splitting reparte el JavaScript en trozos, pero cada trozo es una petición más y una cadena de dependencias más larga. Dividido con criterio, mejora; dividido en cuarenta chunks minúsculos que se piden en cascada, empeora tanto la carga como la interacción.

El orden en que aplicas los remedios cambia lo que miden los siguientes

Las subpartes de una métrica se comportan como vasos comunicantes: reduces una y el tiempo se traslada a otra sin que el total baje. El caso canónico está documentado por el propio equipo de Chrome: si comprimes mejor la imagen del LCP y acortas su descarga, pero el elemento estaba oculto esperando a que terminase de cargar un script, el tiempo que ahorras en la descarga se lo come el retraso de renderizado y el LCP no se mueve ni un milisegundo. Has hecho un trabajo correcto que no ha servido de nada, y peor aún, has generado la evidencia falsa de que “optimizar imágenes no funciona en nuestro sitio”. La regla que me ha ahorrado más tiempo es atacar siempre primero los tramos de espera pura, los que en el desglose del LCP llevan la palabra retraso, y solo después los tramos de transferencia. Si eliminas la espera y luego aceleras la transferencia, las dos mejoras se suman de verdad.

Qué no es un remedio

Cierro con la lista corta de cosas que se proponen habitualmente en reuniones de rendimiento y que no lo son.

  • Cambiar de framework. Puede ser la decisión correcta por otras razones, pero como remedio de rendimiento es la palanca más cara y menos predecible del catálogo. Casi siempre hay dos órdenes de magnitud de mejora disponibles sin tocarlo.
  • Minificar. Es imprescindible y ya lo hace tu bundler. Reduce bytes antes de comprimir, pero después de Brotli la ganancia adicional de minificar es modesta. No es una palanca, es higiene.
  • Reducir el número de peticiones porque sí. Era un mandamiento con HTTP/1.1, donde el paralelismo estaba limitado a unas seis conexiones por origen. Con HTTP/2 y HTTP/3 multiplexados, el número de peticiones importa mucho menos que su prioridad y su tamaño.
  • Subir la puntuación de Lighthouse. Es un indicador, no un objetivo. Los usuarios no experimentan la puntuación.

Con el mapa de causas y el de remedios, ya tienes el esqueleto del track. La última lección del nivel desmonta los mitos que hacen que este mapa se aplique mal.