En el artículo anterior sobre WebPerf Snippets + WebMCP hablé de una alternativa que ya funciona hoy, sin esperar soporte de navegador: los Agent SKILLs.
La idea básica es sencilla: convertir los snippets de análisis de rendimiento en capacidades que un agente de IA pueda usar de forma autónoma, usando Chrome DevTools MCP como capa de ejecución en el navegador. Pero hay una decisión de diseño en la implementación que vale la pena mencionar, porque cambia lo que el agente puede hacer.
El límite de los SKILLs solo de texto
Al construir un SKILL para un agente de IA, el enfoque más directo es poner todo en un archivo markdown: instrucciones, umbrales, ejemplos… y el código JavaScript inline. El agente lee ese archivo al activar el SKILL y tiene todo el contexto.
El problema aparece cuando escala. Con 47 snippets, incluir todo el JavaScript en el markdown supone miles de tokens consumidos en cada invocación, aunque el agente solo necesite medir el LCP. Todo el código viaja al contexto aunque no se use.
Pero hay un problema más sutil: si el JavaScript es solo texto en un markdown, nada garantiza que el agente lo ejecute exactamente como está. Los LLMs pueden “optimizar”, reinterpretar o adaptar código en lugar de copiarlo literalmente. Para medición de rendimiento, eso es exactamente lo que no queremos.
Scripts en el scope del SKILL
El enfoque en WebPerf Snippets es diferente: el JavaScript no está en el SKILL.md. Está en archivos .js que viven en el mismo directorio que el SKILL. Cuando el agente necesita medir el LCP, no genera código, lee scripts/LCP.js y lo ejecuta vía Chrome DevTools MCP.
skills/webperf-core-web-vitals/
├── SKILL.md # Instrucciones, umbrales e índice de scripts
└── scripts/
├── LCP.js
├── CLS.js
├── INP.js
└── ...
El SKILL.md actúa como índice e instrucciones. Los scripts son las herramientas reales. El agente lee el script cuando lo necesita; no antes.
Dos objetivos concretos
Herramientas determinísticas
Cuando el agente recibe la instrucción de medir el LCP, no improvisa JavaScript. Lee scripts/LCP.js, el mismo script que hemos creado, probado y validado, y lo ejecuta. El resultado es consistente entre sesiones, entre agentes y entre modelos.
Esto importa especialmente en diagnóstico de rendimiento. Una medición que varía según cómo el LLM interpreta el código ese día no es una medición fiable. Un script fijo, ejecutado directamente, sí lo es.
Ahorro de tokens
El SKILL.md contiene instrucciones y metadatos. Los scripts son ficheros separados que el agente solo carga cuando los necesita. Si el agente está analizando CLS y no LCP, scripts/LCP.js nunca entra en contexto.
Con 47 snippets distribuidos en 6 SKILLs, la diferencia entre “todo inline” y “scripts como ficheros” es significativa. El agente transfiere tokens solo por lo que usa.
La estructura de los SKILLs
La organización sigue las mismas categorías que los snippets originales:
| SKILL | Snippets | Qué mide |
|---|---|---|
webperf-core-web-vitals | 7 | LCP, CLS, INP |
webperf-loading | 28 | TTFB, FCP, scripts, fuentes |
webperf-interaction | 8 | LoAF, LongTask, scroll |
webperf-media | 3 | Imágenes, video |
webperf-resources | 1 | Ancho de banda |
webperf | — | Meta-SKILL: router central |
Cada SKILL tiene su propio SKILL.md con:
- Índice de scripts disponibles
- Umbrales de referencia (qué valores son buenos, malos, o requieren investigación)
- Instrucciones de interpretación de resultados
Esto nos facilita el mantenimiento de los SKILLs, tanto en los umbrales como en la actualización de scripts o la incorporación de nuevos.
Ya se me ocurre que podemos mejorar los scripts, optimizando los reportes que genera con
console.{log,info,error,table}, para facilitar los informes presentados en la consola, pero ese trabajo lo podemos delegar al LLM ya que lo podrá hacer mejor y adaptar la salida según la necesidad, un markdown, un PDF, un mensaje de alerta en Slack, etc…
Árboles de decisión y workflows
La parte más interesante no son los scripts individuales, sino los workflows que orquestan varios scripts según los resultados obtenidos.
Un ejemplo real: si el TTFB supera los 600ms, el agente no para ahí. El workflow le indica que debe ejecutar TTFB-Sub-Parts.js para desglosar el tiempo en DNS, conexión TCP, negociación TLS y tiempo de servidor. Con ese desglose, la recomendación es concreta en lugar de genérica.
TTFB > 600ms
→ ejecutar TTFB-Sub-Parts.js
→ si DNS > 100ms → problema de DNS/CDN
→ si connection > 200ms → problema de red/distancia al servidor
→ si server > 300ms → problema de backend
Los SKILLs incluyen 8 workflows principales con 16 árboles de decisión de este tipo. El agente sabe qué ejecutar a continuación según lo que encuentre, sin que quien analiza tenga que dirigirlo paso a paso.
Chrome DevTools MCP como capa de ejecución
Para que todo esto funcione, el agente necesita poder navegar a una página y ejecutar JavaScript en ella. Eso es exactamente lo que proporciona Chrome DevTools MCP.
El flujo completo con un agente como Claude Code:
1. El agente navega a la URL con `navigate_page`
2. Lee el script relevante del SKILL (scripts/LCP.js)
3. Lo ejecuta en el navegador con `evaluate_script`
4. Captura el output de consola
5. Compara el resultado con los umbrales del `SKILL.md`
6. Si se supera un umbral, activa el workflow correspondiente
El agente no improvisa JavaScript. No interpreta una interfaz visual. No simula clics. Lee un script predefinido, lo ejecuta, lee el resultado. Determinístico.
Instalación
La forma más rápida es con la Skills CLI, que instala las SKILLs directamente desde el repositorio al entorno global ~/.claude/skills/:
npx skills add nucliweb/webperf-snippets
Si preferís instalación local (proyecto actual) o global desde el repositorio clonado:
# Local (proyecto actual → .claude/skills/)
npm run install-skills
# Global (todos los proyectos → ~/.claude/skills/)
npm run install-global
Una vez instalados, el agente los descubre automáticamente al necesitarlos. No hace falta configuración adicional.
En la práctica
En mis auditorías de rendimiento, el flujo que más se repite es: navega a la página, mide las Core Web Vitals, identifica cuál está fuera de umbral, profundiza en esa métrica concreta. Con los WebPerf SKILLs, ese flujo pasa de ser una serie de instrucciones manuales a una capacidad que el agente ejecuta de forma autónoma. Ya tengo ganas de probar este flujo en un OpenClaw.
No se trata de que la IA “entienda” el rendimiento web mejor que quien hace la auditoría. Se trata de que la IA tenga las herramientas correctas para recopilar datos de forma fiable, de modo que quien analiza pueda centrarse en interpretar, decidir y priorizar según impacto, no en ejecutar scripts repetitivos.
Caso real: detectando el antipatrón Preload + Async
Con Claude Code, Chrome DevTools MCP y los WebPerf SKILLs instalados globalmente, ejecuté este prompt:
Check if the page https://cocunat.com/es-es/products/clinical-beauty-filler-duo
has resources with Preload + Async/Defer

El agente navegó a la página, seleccionó el SKILL webperf-loading, leyó el script correspondiente y lo ejecutó en el navegador. El resultado: 7 antipatrones encontrados, todos del mismo origen.

Los 7 scripts del banner de consentimiento de Usercentrics (web.cmp.usercentrics.eu) están cargados con async pero también tienen rel="preload". Una combinación que parece razonable, descubrir el recurso pronto y cargarlo sin bloquear, pero que produce el efecto contrario al esperado.
async baja la prioridad del script a Lowest/Low. rel="preload" la sube a Medium/High. El resultado es una escalada de prioridad que pone estos scripts de terceros compitiendo con recursos críticos: la imagen LCP, las fuentes, el CSS. El navegador los descubre antes de tiempo y les da preferencia que no merecen.
El agente identificó el problema, explicó el mecanismo y propuso dos opciones de solución:
Opción 1 (recomendada): Eliminar los preloads y dejar que los scripts async carguen a su prioridad natural.
<!-- ❌ Eliminar -->
<link rel="preload" href="WebSdk.lib.91f0d3cd.js" as="script" />
<!-- ✅ Mantener solo esto -->
<script src="WebSdk.lib.91f0d3cd.js" async></script>
Opción 2: Mantener el preload añadiendo fetchpriority="low", para conservar el descubrimiento temprano sin escalar la prioridad.
<link rel="preload" href="WebSdk.lib.91f0d3cd.js" as="script" />
<script src="WebSdk.lib.91f0d3cd.js" async fetchpriority="low"></script>
Y añadió una nota relevante: como Usercentrics es una herramienta de terceros, la corrección probablemente hay que reportarla a su soporte o gestionarla desde su dashboard o la integración con el tag manager.
Todo esto a partir de un prompt de una línea. El agente no generó JavaScript ad hoc, no intentó interpretar el HTML visualmente ni improvisó lógica de detección. Leyó el script del SKILL, lo ejecutó y entregó un diagnóstico accionable.
Ojo, que esta solución no es una bala de plata, puede ser que para las primeras visitas, nos interese que la carga de los scripts del banner de consentimientos se prioricen para anticipar el renderizado. En muchos casos la modal del CMP es el elemento LCP de las primeras visitas. En ese caso, se podría plantear una estrategia Server-Side Conditional Loading, hablo de ello en Optimización de scripts de consentimiento para Core Web Vitals. Esto demuestra que con la IA, podemos agilizar nuestros análisis y mejorar los reportes, pero debemos saber qué medir, cómo interpretar, qué priorizar y cuál es la mejor estrategia según el producto.
Conclusión
La distinción entre “SKILL con texto” y “SKILL con scripts en scope” parece pequeña, pero cambia lo que el sistema puede hacer: de un agente que improvisa código a partir de instrucciones, a un agente que ejecuta herramientas validadas de forma consistente. Determinismo en la medición; ahorro en tokens; autonomía real en el análisis.
WebMCP y los Agent SKILLs son dos aproximaciones al mismo objetivo. Una espera a que el estándar madure en el navegador; la otra funciona hoy con las herramientas que ya podemos utilizar.