JavaScript es el recurso más caro de una página web. No solo por los bytes que transfiere, sino por el tiempo de CPU que consume al parsearse, compilarse y ejecutarse. Y el problema real es que entre un 35% y un 45% del JavaScript que carga una web media nunca se ejecuta durante la primera interacción del usuario.
Eliminar ese código innecesario mejora directamente las métricas de velocidad web que Google usa como señales de ranking: LCP, INP y tiempo total de carga.
Por qué el JavaScript no utilizado daña tu Core Web Vitals
Cuando el navegador descarga un archivo JavaScript, tiene que hacer tres cosas antes de que el código sea funcional: descargarlo, parsearlo y ejecutarlo. Cada una de estas fases consume tiempo y recursos.
Según web.dev, cada 100KB de JavaScript añade entre 150 y 300ms de tiempo de procesamiento en un dispositivo móvil de gama media. Un smartphone con un procesador Snapdragon 680 procesa JavaScript entre 3 y 5 veces más lento que un MacBook Pro.
El impacto en Core Web Vitals es triple:
- LCP: scripts que bloquean el renderizado retrasan la pintura del contenido principal. Un script síncrono en el head puede añadir 500ms o más al LCP.
- INP (Interaction to Next Paint): el hilo principal del navegador no puede procesar interacciones del usuario mientras ejecuta JavaScript. Cuanto más JS se ejecute, mayor será el retraso entre el clic del usuario y la respuesta visual.
- TBT (Total Blocking Time): tareas de JavaScript que duran más de 50ms bloquean el hilo principal. El TBT acumulado correlaciona directamente con una mala experiencia de interactividad.
El código JavaScript que nunca se ejecuta durante la carga inicial sigue consumiendo tiempo de parseo y compilación. El navegador no puede saber de antemano qué funciones se ejecutarán, así que procesa todo el archivo.
Cómo identificar JavaScript no utilizado con Chrome DevTools
Chrome DevTools incluye la herramienta Coverage, que mide qué porcentaje de cada archivo CSS y JavaScript se ejecuta realmente durante la carga y la interacción.
Pasos para usarla:
- Abre Chrome DevTools (F12).
- Abre el panel Coverage: Ctrl+Shift+P > escribe “Coverage” > selecciona “Show Coverage”.
- Pulsa el botón de recarga para iniciar la grabación desde la carga de la página.
- Interactúa con la página (scroll, clics en menús, formularios) para simular uso real.
- Observa la columna “Usage Visualization”: las barras rojas indican código no ejecutado.
Lo que debes buscar:
- Archivos con más del 50% de código no usado: son candidatos a optimización o eliminación.
- Bundles de terceros grandes: bibliotecas completas cargadas para usar una sola función.
- Polyfills innecesarios: código de compatibilidad para navegadores que tus usuarios no usan.
La pestaña Network complementa este análisis mostrando el tamaño de cada archivo JavaScript descargado y si bloquea el renderizado (columna “Initiator” y marca “render-blocking”).
JavaScript de terceros: el peor culpable (y cómo gestionarlo)
Los scripts de terceros representan el 57% del JavaScript total en webs comerciales según HTTP Archive. Analytics, chatbots, pixels de remarketing, widgets de redes sociales, herramientas de A/B testing: cada uno añade su payload de JavaScript al hilo principal.
El problema no es solo el peso. Cada script de terceros puede:
- Hacer peticiones HTTP adicionales que compiten por ancho de banda.
- Ejecutar código en el hilo principal que bloquea la interactividad.
- Cargar sus propias dependencias (un widget de chat puede traer React completo aunque tu sitio no lo use).
- Fallar silenciosamente y dejar listeners huérfanos que consumen memoria.
Estrategias para gestionar scripts de terceros
Auditar regularmente: revisa cada script de terceros y pregunta si realmente lo necesitas. Un pixel de una campaña que terminó hace 6 meses sigue ejecutándose en cada carga de página.
Consolidar con Google Tag Manager: GTM permite gestionar múltiples scripts desde una interfaz centralizada. Aunque GTM tiene su propio coste de rendimiento (~30-80KB), consolidar 5-10 scripts individuales en GTM suele ser más eficiente.
Cargar después de la interacción: para scripts no críticos (chat en vivo, encuestas), retrasa la carga hasta que el usuario interactúe con la página. Un listener de scroll o clic que inyecta el script bajo demanda elimina su impacto en la carga inicial.
Usar facades: una imagen estática o botón que simula el aspecto del widget real. Cuando el usuario hace clic, se carga el script completo. YouTube embed es el ejemplo clásico: un thumbnail con botón de play que carga el iframe solo al hacer clic.
Tree shaking y code splitting: eliminar código muerto en el build
Tree shaking es una técnica de optimización que analiza las importaciones de tu código y elimina las funciones y módulos que no se usan. Los bundlers modernos (webpack, Rollup, esbuild, Vite) lo implementan de forma nativa cuando usas ES Modules (import/export).
Para que tree shaking funcione correctamente:
- Usa
import { specificFunction } from 'library'en vez deimport * as library from 'library'. - Asegúrate de que las dependencias tienen
"sideEffects": falseen su package.json, o declara los side effects explícitamente. - Evita re-exportar módulos completos en archivos barrel (index.ts que re-exportan todo).
Code splitting divide tu JavaScript en chunks que se cargan bajo demanda. En vez de un bundle monolítico de 500KB, generas chunks de 50-100KB que se cargan solo cuando la ruta o funcionalidad los necesita.
Los frameworks modernos implementan code splitting automáticamente:
- Astro usa island architecture: los componentes interactivos solo se hidratan cuando son visibles (
client:visible), eliminando todo el JavaScript de los componentes estáticos. - React con lazy(): permite cargar componentes bajo demanda con
React.lazy()ySuspense. - Dynamic imports:
import('./module.js')carga un módulo solo cuando se ejecuta esa línea de código.
La combinación de tree shaking y code splitting puede reducir el JavaScript inicial entre un 40% y un 70%, dependiendo del tamaño del bundle original.
Diferir y cargar de forma asíncrona: defer vs async
Los atributos defer y async en la etiqueta <script> controlan cuándo se descarga y ejecuta el JavaScript. Usarlos correctamente evita que los scripts bloqueen el renderizado del HTML.
Sin atributos (<script src="app.js">): el navegador detiene el parseo del HTML, descarga el script, lo ejecuta y luego continúa con el HTML. Es el peor escenario para rendimiento.
async (<script async src="app.js">): el navegador descarga el script en paralelo al parseo del HTML, pero cuando termina la descarga, detiene el parseo para ejecutarlo. El orden de ejecución no está garantizado entre scripts con async.
defer (<script defer src="app.js">): el navegador descarga el script en paralelo al parseo del HTML y lo ejecuta después de que el HTML se haya parseado completamente. El orden de ejecución se respeta entre scripts con defer.
Cuándo usar cada uno
- defer: para la mayoría de scripts. Garantiza que el HTML se parsea sin interrupciones y que los scripts se ejecutan en orden. Es la opción por defecto recomendada.
- async: para scripts independientes que no dependen del DOM ni de otros scripts, como analytics o pixels de seguimiento.
- Sin atributos: solo para scripts críticos que deben ejecutarse antes de que el contenido sea visible (casos muy excepcionales).
Para scripts con problemas conocidos de rendimiento JavaScript, la combinación de defer con code splitting asegura que el hilo principal permanezca libre para responder a las interacciones del usuario.
Preguntas frecuentes sobre JavaScript y rendimiento
¿Cuánto JavaScript es demasiado para una web?
No hay un límite absoluto, pero Google recomienda mantener el JavaScript total por debajo de 300KB comprimido para una buena experiencia en dispositivos móviles. Sitios que superan 1MB de JS sin comprimir suelen tener problemas de INP y tiempo de carga.
¿Los plugins de WordPress añaden mucho JavaScript innecesario?
Sí. Cada plugin de WordPress puede añadir entre 20KB y 200KB de JavaScript. Los peores culpables son los page builders, sliders, chats en vivo y plugins de redes sociales. La solución es auditar qué plugins cargan JS, desactivar los innecesarios y usar alternativas ligeras.
¿Cómo cargo scripts de terceros sin que dañen mi rendimiento?
Usa el atributo defer para scripts que no son críticos en la carga inicial. Para scripts pesados (chat, analytics avanzado), retrasa su carga hasta la primera interacción del usuario. Para scripts de seguimiento, evalúa si Google Tag Manager puede consolidar varios en uno solo.
Reducir el JavaScript innecesario es una de las optimizaciones con mayor impacto en Core Web Vitals. La mayoría de sitios que auditamos tienen entre un 35% y un 45% de JS que nunca se ejecuta en la carga inicial — el punto de partida es la pestaña Coverage de Chrome DevTools, que lo muestra en 60 segundos sin instalar nada. Si quieres que analicemos el peso y la ejecución de JavaScript en tu sitio, contacta con nosotros.
Comparte este artículo
Si te ha resultado útil este contenido, compártelo con tus colegas.
Preguntas Frecuentes
¿Google puede rastrear sitios web con mucho JavaScript?
Sí, Google puede rastrear JavaScript, pero con limitaciones. Para optimizar usa server-side rendering, implementa hydration progresiva, asegura que el contenido crítico sea accesible sin JS y usa técnicas como lazy loading responsable.
¿Qué es mejor para SEO: SPA o páginas tradicionales?
Las páginas tradicionales suelen ser mejores para SEO por su facilidad de crawling. Las SPAs requieren configuración adicional (SSR, prerendering) pero pueden ofrecer mejor UX. La elección depende de tus objetivos específicos y recursos técnicos.
¿Con qué frecuencia publican contenido nuevo?
Publicamos artículos nuevos semanalmente, enfocados en las últimas tendencias de SEO técnico, casos de estudio reales y mejores prácticas. Suscríbete a nuestro newsletter para no perderte ninguna actualización.
¿Los consejos son aplicables a cualquier tipo de sitio web?
Nuestros consejos se adaptan a diferentes tipos de sitios: ecommerce, blogs, sitios corporativos y aplicaciones web. Siempre indicamos cuándo una técnica es específica para cierto tipo de sitio o requerimientos técnicos.