Web Performance

Por qué tu sitio debería enviar menos solicitudes, no solicitudes más pequeñas

Los archivos diminutos no son gratis. El HTTP moderno redujo la sobrecarga de las solicitudes, no la volvió irrelevante.

The Wux Webtools Team The Wux Webtools Team 11 min de lectura Asistido por IA, revisado por humanos
A stylized browser waterfall showing many small requests simplified into fewer intentional requests.
Tabla de contenido
  1. El cómodo mito de “solo haz que cada archivo sea más pequeño”
  2. Las solicitudes no son solo bytes
  3. “Pero HTTP/2 arregló esto”, en gran parte no
  4. La cascada es donde vive la verdad
  5. Los archivos más pequeños siguen importando, pero no por igual
  6. Los costes ocultos de muchos archivos pequeños
  7. 1. Descubrimiento tardío
  8. 2. Sobrecarga de headers
  9. 3. Interrupción del hilo principal
  10. 4. Complejidad de caché
  11. El bundling ha vuelto, pero con criterio
  12. Las solicitudes de terceros merecen sospecha extra
  13. Una checklist práctica para reducir solicitudes
  14. Eliminar
  15. Combinar con criterio
  16. Diferir
  17. Cachear correctamente
  18. Volver a medir
  19. Cómo se ve algo bien hecho

El cómodo mito de “solo haz que cada archivo sea más pequeño”

Durante años, los consejos de rendimiento web sonaban simples: comprime todo, minifica todo, haz que cada recurso sea más pequeño.

Ese consejo sigue siendo correcto en términos generales. Un script de 40 KB suele ser mejor que uno de 400 KB. Una imagen optimizada es mejor que una exportación sin procesar. Brotli, AVIF, la minificación de CSS, tree shaking y el subsetting de fuentes importan.

Pero en muchos sitios en producción, el problema más grande ya no es un único archivo sobredimensionado. Es la cantidad de cosas que el navegador tiene que pedir antes de que la página se sienta usable.

Una página puede parecer disciplinada en el tamaño de sus archivos y aun así ser lenta porque envía 120 solicitudes: fragmentos de CSS, chunks de JavaScript, etiquetas de terceros, archivos de fuentes, píxeles de seguimiento, sprites de iconos, endpoints JSON, preloads, beacons de analytics y revalidaciones de caché. Cada una puede ser “pequeña”. Juntas, crean una cascada larga y frágil.

La regla práctica es esta: una vez que los recursos individuales están razonablemente comprimidos, reducir la cantidad de solicitudes suele mejorar más la experiencia de usuario que recortar unos pocos kilobytes de cada archivo.

Las solicitudes no son solo bytes

Una solicitud de red no es solo una transferencia de datos. Es una secuencia de trabajo.

El navegador tiene que descubrir el recurso, decidir cuándo obtenerlo, programarlo frente a otros recursos, enviar headers, esperar al servidor, recibir headers, parsear la respuesta, a menudo descomprimirla y luego hacer algo útil con ella.

Ese “algo útil” puede ser costoso. Un archivo JavaScript debe parsearse, compilarse y ejecutarse. Un archivo CSS puede bloquear el renderizado. Un archivo de fuente puede retrasar el texto legible o causar cambios de layout. Una imagen puede afectar al elemento de Largest Contentful Paint. Un script de terceros puede traer su propia cadena de dependencias.

Por eso la cantidad de solicitudes sigue importando incluso cuando los archivos son pequeños. Un script de 3 KB puede ser peor que una imagen de 30 KB si bloquea el renderizado, llega tarde y se ejecuta en el hilo principal en el momento equivocado.

Si estás leyendo un informe de Lighthouse y sientes que te castigan con decenas de advertencias separadas, empieza mirando la cascada de solicitudes en lugar de las puntuaciones individuales. Tenemos una guía práctica en cómo leer un informe de Lighthouse sin entrar en pánico, pero la versión corta es: encuentra qué bloquea el primer renderizado y qué retrasa el contenido principal.

“Pero HTTP/2 arregló esto”, en gran parte no

HTTP/2 y HTTP/3 cambiaron la economía de las solicitudes. Introdujeron multiplexing, compresión de headers y un mejor comportamiento de conexión. En términos simples, los navegadores se volvieron mucho mejores enviando múltiples solicitudes sobre menos conexiones.

Fue una mejora real. También acabó con algunos hábitos antiguos, como los sprites CSS extremos y los bundles gigantes concatenados creados solo para evitar límites de conexión.

Pero HTTP/2 no hizo que las solicitudes fueran gratis.

El multiplexing ayuda cuando muchos recursos comparten una conexión, pero el navegador todavía tiene que priorizarlos. Los servidores todavía tienen que responder. El cliente todavía tiene que procesar cada respuesta. La congestión, la pérdida de paquetes, la negociación TLS, la búsqueda DNS, los fallos de caché y la presión sobre el hilo principal siguen existiendo.

HTTP/3 mejora parte del comportamiento de transporte, especialmente alrededor de la migración de conexión y el head-of-line blocking en la capa de transporte. No elimina el coste de descubrir, programar, descargar, parsear y ejecutar recursos.

Así que el objetivo moderno no es “agrupar todo en un archivo enorme”. Es “enviar menos solicitudes críticas y hacer que las solicitudes restantes sean intencionales”.

La cascada es donde vive la verdad

Los problemas de rendimiento rara vez se anuncian en una sola métrica. Aparecen como una forma.

Abre el panel de red del navegador y mira los primeros segundos. Pregunta:

  • ¿Cuántas solicitudes empiezan antes de que aparezca el contenido principal?
  • ¿Qué solicitudes bloquean el renderizado?
  • ¿Los recursos importantes se descubren tarde?
  • ¿Los scripts de terceros compiten con CSS, fuentes o imágenes propias?
  • ¿Muchos archivos devuelven respuestas 304 en lugar de servirse directamente desde la caché?
  • ¿Los iconos, fuentes o fragmentos de UI están divididos en más archivos de los que la página necesita?

Una página rápida suele tener una cascada inicial aburrida. Un número pequeño de recursos críticos llega pronto. Los recursos no críticos esperan. Los scripts de terceros se retrasan, se limitan o se eliminan. El navegador no se ve obligado a manejar veinte prioridades antes de poder pintar la página.

Una página lenta suele tener una cascada nerviosa: muchos archivos pequeños, muchos orígenes y muchos descubrimientos tardíos.

Los archivos más pequeños siguen importando, pero no por igual

Esto no es un argumento contra la compresión o la optimización. Es un argumento contra optimizar bytes mientras se ignora la coordinación.

Los archivos más pequeños importan más cuando el recurso es grande, bloquea el renderizado o forma parte de la ruta del contenido principal. Por ejemplo:

  • La imagen hero debe tener el tamaño y la codificación adecuados.
  • El CSS que bloquea el renderizado debe ser ligero.
  • El JavaScript necesario para la primera interacción debe ser mínimo.
  • Las fuentes deben estar subset, comprimidas y limitadas a los pesos realmente usados.

Las fuentes son un ejemplo común. Los equipos suelen obsesionarse con si un archivo de fuente pesa 24 KB o 31 KB, mientras envían seis pesos, dos estilos y varias familias. La mejor solución no es recortar 7 KB de un archivo. Es enviar menos archivos de fuentes. Si la tipografía forma parte de tu trabajo de rendimiento, las fuentes web siguen siendo una de las mejoras más fáciles en la mayoría de los sitios.

Las imágenes siguen el mismo patrón. AVIF o WebP pueden ahorrar una cantidad significativa de bytes, pero enviar diez imágenes decorativas above the fold sigue siendo un mal plan. Elige mejores formatos, sí, pero también cuestiona si cada imagen necesita solicitarse. Para decisiones de formato, nuestra guía sobre cuándo AVIF supera a WebP y cuándo no es un complemento útil para este trabajo sobre cantidad de solicitudes.

Los costes ocultos de muchos archivos pequeños

Muchas solicitudes pequeñas tienden a crear problemas que no aparecen si solo miras el total de bytes transferidos.

1. Descubrimiento tardío

Los navegadores no pueden solicitar lo que no han descubierto. Un archivo CSS puede referenciar una fuente. Un script puede importar otro script. Un componente puede solicitar JSON después de la hidratación. Cada dependencia crea otro paso en la cadena.

Cuanto más profunda es la cadena, más tarde empieza el trabajo importante.

2. Sobrecarga de headers

Cada solicitud y respuesta incluye headers. La compresión de headers ayuda, especialmente sobre HTTP/2 y HTTP/3, pero no elimina la sobrecarga. Las cookies pueden empeorar mucho esto. Si tu sitio envía cookies grandes con cada solicitud, los recursos diminutos se vuelven menos diminutos en la práctica.

Esta es una razón por la que los recursos estáticos a menudo deberían vivir en rutas o dominios sin cookies, y por la que los headers de caché merecen atención. Si los headers se comportan de forma extraña en producción, depurar redirecciones y headers HTTP suele ser más rápido que adivinar.

3. Interrupción del hilo principal

Muchos chunks de JavaScript pueden crear trabajo repetido de parseo y ejecución. Aunque cada chunk sea pequeño, el navegador puede seguir deteniéndose para evaluar código. Esto puede perjudicar Interaction to Next Paint y hacer que la página se sienta inestable.

Al usuario no le importa que cada archivo fuera pequeño. Le importa que tocar un menú tardara 600 milisegundos.

4. Complejidad de caché

Dividir recursos puede mejorar la caché cuando se hace con cuidado. Un bundle de vendor estable y un bundle de app cambiante pueden ser una buena división.

Pero el chunking excesivo puede salir mal. Más archivos significan más búsquedas de caché, más oportunidades de revalidación, más coordinación de versiones y más formas de invalidar accidentalmente recursos que no necesitaban cambiar.

El bundling ha vuelto, pero con criterio

La primera era del rendimiento web amaba el bundling porque los navegadores tenían límites estrictos de conexión. Luego llegó HTTP/2 y muchos equipos se inclinaron con fuerza hacia el code splitting agresivo. Parte de eso fue útil. Parte se convirtió en superstición.

El punto medio sensato es el bundling consciente de la ruta.

Para un sitio típico de marketing o contenidos:

  • Inserta inline o carga solo el CSS necesario para el renderizado inicial.
  • Mantén pequeño el JavaScript global.
  • Evita dividir módulos diminutos en solicitudes de red separadas.
  • Retrasa las funciones interactivas que no se necesitan de inmediato.
  • Elimina los scripts de terceros que no justifican su coste.

Para una aplicación:

  • Divide por ruta o funcionalidad principal, no por cada componente.
  • Mantén las dependencias compartidas estables y cacheables.
  • Haz preload solo de recursos que definitivamente se necesitarán pronto.
  • Evita cargar código de admin, dashboard, editor o experimentos en páginas públicas.
  • Mide el coste de interacción, no solo el tamaño del bundle.

El bundling no es automáticamente bueno. El code splitting no es automáticamente bueno. La pregunta útil es: ¿esta división ayuda al navegador a entregar antes la siguiente experiencia significativa para el usuario?

Las solicitudes de terceros merecen sospecha extra

Las solicitudes propias al menos están bajo tu control. Las solicitudes de terceros suelen ser más lentas, menos predecibles y más costosas de lo que parecen.

Un solo tag manager puede activar analytics, anuncios, heatmaps, widgets de chat, pruebas A/B, herramientas de consentimiento y scripts de personalización. Cada proveedor puede traer más solicitudes. Algunas se ejecutarán pronto. Algunas bloquearán el hilo principal. Algunas cambiarán sin pasar por tu proceso de release.

La mejor optimización de terceros es eliminar. La segunda mejor es retrasar.

Antes de añadir un script de terceros, pregunta:

  • ¿Esto necesita cargarse antes de que el usuario vea la página?
  • ¿Necesita cargarse en todas las páginas?
  • ¿Puede cargarse después del consentimiento, la interacción o el tiempo idle?
  • ¿Quién es responsable internamente?
  • ¿Qué métrica demuestra que merece el coste de rendimiento?

Aquí es donde el rendimiento se convierte en gobernanza. Alguien tiene que tener permiso para decir que no.

Una checklist práctica para reducir solicitudes

Empieza por las páginas que más importan: homepage, página de precios, página de producto, checkout, signup o principales landing pages. Luego recorre la cascada.

Eliminar

  • Elimina JavaScript y CSS no utilizados.
  • Elimina experimentos antiguos, píxeles abandonados y analytics duplicados.
  • Descarta pesos de fuente e icon libraries no utilizados.
  • Sustituye imágenes decorativas por CSS cuando corresponda.

Combinar con criterio

  • Agrupa módulos JavaScript diminutos que siempre se cargan juntos.
  • Fusiona archivos CSS pequeños que bloquean la misma ruta de renderizado.
  • Usa SVG sprites o SVG inline para iconos repetidos cuando reduzca solicitudes sin perjudicar la mantenibilidad.

Diferir

  • Carga de forma lazy las imágenes below the fold.
  • Retrasa scripts no críticos hasta después del primer pintado o de la interacción del usuario.
  • Carga comentarios, embeds, mapas, chat y reproductores de video solo cuando se necesiten.

Cachear correctamente

  • Usa caché de larga duración para recursos estáticos versionados.
  • Evita revalidaciones innecesarias para archivos que rara vez cambian.
  • Mantén el HTML fresco, pero permite que los recursos con hash permanezcan cacheados.

Volver a medir

Después de cada cambio, revisa la cascada otra vez. El objetivo no es una puntuación perfecta. El objetivo es tener menos solicitudes críticas, un renderizado útil más temprano y menos interrupción del hilo principal.

Cómo se ve algo bien hecho

Una página sana no necesariamente tiene la menor cantidad posible de solicitudes. Tiene una ruta crítica pequeña y deliberada.

El navegador obtiene HTML, CSS esencial, la imagen del contenido principal si existe, quizá un script pequeño necesario para la navegación o la interacción above-the-fold, y el conjunto mínimo de fuentes necesario para que el texto sea legible. Todo lo demás espera su turno.

Esa es la diferencia entre una página que simplemente está optimizada y una página que se siente rápida.

Reducir archivos sigue valiendo la pena. Pero si el sitio ya está razonablemente comprimido, la siguiente mejora de rendimiento normalmente no es ahorrar otros 2 KB de un bundle. Es una solicitud bloqueante menos, un archivo de fuente menos, un script de terceros menos, una cadena de dependencias menos.

Menos solicitudes simplifican el trabajo del navegador. Lo simple es rápido más a menudo de lo que nos gusta admitir.

Preguntas frecuentes

¿Es mejor un bundle grande que muchos archivos pequeños?
No automáticamente. Un bundle enorme puede retrasarlo todo, especialmente en la primera carga. Muchos archivos diminutos pueden crear sobrecarga de programación y ejecución. El mejor patrón es agrupar recursos que siempre se necesitan juntos y dividir por ruta o funcionalidad principal.
¿HTTP/2 significa que la cantidad de solicitudes ya no importa?
No. HTTP/2 reduce parte de la sobrecarga de conexión mediante multiplexing y compresión de headers, pero cada solicitud sigue teniendo costes de descubrimiento, priorización, servidor, caché, parseo y ejecución.
¿Debería insertar inline todo el CSS crítico?
Insertar inline una pequeña cantidad de CSS verdaderamente crítico puede ayudar al primer renderizado, pero insertar demasiado hace que el HTML sea más pesado y más difícil de cachear. Manténlo mínimo y mide el efecto.
¿Cuál es el lugar más fácil para reducir solicitudes?
Las fuentes y los scripts de terceros suelen ser las mejoras más rápidas. Muchos sitios envían pesos de fuente no usados, analytics duplicados, píxeles antiguos, widgets de chat o embeds que no necesitan cargarse de inmediato.
¿Cuántas solicitudes debería tener una página?
No hay un objetivo universal. Una página de contenido pequeña debería tener muy pocas solicitudes críticas. Una app compleja puede necesitar más. Concéntrate en reducir solicitudes antes del primer renderizado y antes de la ruta principal de interacción.

Fuentes y lecturas adicionales

  1. MDN Web Docs: HTTP caching
  2. web.dev: Optimize Largest Contentful Paint
  3. RFC 9113: HTTP/2
  4. HTTP Archive Web Almanac: Page Weight
Sobre el autor
The Wux Webtools Team

Última actualización:

Sigue leyendo