{"schemaVersion":1,"id":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation","title":"Speculation Rules API: Pre-renderizado de Páginas Antes de la Navegación e Impacto Medido en Core Web Vitals","description":"Un análisis técnico de la Speculation Rules API para prerender y prefetch, estrategias de especulación basadas en confianza, detalles de implementación en Chrome, y mejoras medibles en Core Web Vitals incluyendo optimización de INP.","language":"es","datePublished":"2026-03-05","dateModified":null,"contentFormat":"text/markdown","content":"Web Performance\n\n# Speculation Rules API: Pre-renderizado de Páginas Antes de la Navegación e Impacto Medido en Core Web Vitals\n\n2026-03-057 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/speculation-rules-api-prerender-navigation>)\n\n## La API: Cómo Funciona\n\nLas speculation rules se declaran como un objeto JSON dentro de un tag ` <script type=\"speculationrules\"> `:\n\n```html\n<script type=\"speculationrules\">\n{\n \"prerender\": [\n {\n \"where\": {\n \"and\": [\n { \"href_matches\": \"/*\" },\n { \"not\": { \"href_matches\": \"/logout\" } },\n { \"not\": { \"href_matches\": \"/api/*\" } },\n { \"not\": { \"selector_matches\": \".no-prerender\" } }\n ]\n },\n \"eagerness\": \"moderate\"\n }\n ],\n \"prefetch\": [\n {\n \"where\": {\n \"href_matches\": \"/blog/*\"\n },\n \"eagerness\": \"conservative\"\n }\n ]\n}\n</script>\n```\n\nEsto le dice a Chrome: \"Para cualquier link interno que no sea la página de logout o una ruta de API, pre-renderizala cuando el usuario muestre interés moderado (hover por 200ms). Para links del blog, prefetchealos con intención conservadora (pointerdown, el momento del click).\"\n\nLa cláusula ` where ` soporta pattern matching de URLs (` href_matches `) y matching de selectores CSS (` selector_matches `). Puede componer reglas con ` and `, ` or `, y ` not `. Esto es vastamente más poderoso que el viejo ` <link rel=prerender> ` que solo podía apuntar a una sola URL.\n\n## Niveles de Eagerness: El Espectro de Confianza\n\nHay cuatro niveles de eagerness, cada uno mapeando a una señal diferente de intención del usuario:\n\n| Eagerness | Trigger | Lead Time Típico | Caso de Uso |\n| --- | --- | --- | --- |\n| ` immediate ` | Carga de página | Segundos | Navegación siguiente conocida (paso 2 de wizard) |\n| ` eager ` | Link se hace visible | Segundos | Navegación de alta probabilidad |\n| ` moderate ` | Hover (200ms) | 200-800ms | Links de navegación general |\n| ` conservative ` | Pointerdown/touchstart | 50-200ms | Páginas de menor confianza o costosas |\n\nEn la práctica, ` moderate ` es el punto óptimo para la mayoría de los sitios. Te da 200-800ms de lead time (duración del hover antes del click), que es suficiente para pre-renderizar completamente una página típica.\n\nInstrumenté el comportamiento de hover en un sitio de documentación con 40.000 visitantes diarios:\n\n```javascript\ndocument.querySelectorAll('a[href]').forEach(link => {\n let hoverStart = 0;\n\n link.addEventListener('pointerenter', () => {\n hoverStart = performance.now();\n });\n\n link.addEventListener('click', () => {\n const hoverDuration = performance.now() - hoverStart;\n navigator.sendBeacon('/analytics/hover', JSON.stringify({\n duration: Math.round(hoverDuration),\n url: link.href,\n clicked: true,\n }));\n });\n});\n```\n\nResultados de 2 semanas de datos:\n\n- Mediana de hover-a-click: 380ms\n- Percentil 75: 620ms\n- Percentil 90: 1.100ms\n- Tasa hover-a-click (hover \\> 200ms): 68% de los hovers resultaron en click\n\nCon eagerness ` moderate ` (umbral de 200ms), predecimos correctamente el 68% de las navegaciones. El 32% de prerenders desperdiciados es un costo de ancho de banda, pero Chrome maneja el lifecycle del prerender agresivamente, si la memoria está limitada, desaloja páginas pre-renderizadas.\n\n## Speculation Rules Dinámicas\n\nLas reglas estáticas en HTML funcionan para case es simples, pero los sitios reales necesitan reglas dinámicas basadas en comportamiento del usuario, A/B tests, o personalización:\n\n```javascript\nfunction updateSpeculationRules(urls) {\n document.querySelectorAll('script[type=\"speculationrules\"]')\n .forEach(el => el.remove());\n\n const script = document.createElement('script');\n script.type = 'speculationrules';\n script.textContent = JSON.stringify({\n prerender: [{\n urls: urls.highConfidence,\n eagerness: 'moderate',\n }],\n prefetch: [{\n urls: urls.lowConfidence,\n eagerness: 'conservative',\n }],\n });\n document.head.appendChild(script);\n}\n\n// Predecir próxima página basado en profundidad de scroll\nfunction predictNextPage() {\n const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight);\n\n if (scrollPercent > 0.7) {\n const nextLink = document.querySelector('a.pagination-next');\n if (nextLink) {\n updateSpeculationRules({\n highConfidence: [nextLink.href],\n lowConfidence: [],\n });\n }\n }\n}\n\nwindow.addEventListener('scroll', debounce(predictNextPage, 500), { passive: true });\n```\n\nUso este patrón en un blog donde los artículos tienen links de \"próximo post\". Cuando el usuario scrollea más del 70% del artículo, agrego una regla de prerender para el próximo post. Para cuando llegan abajo y hacen click en \"Siguiente,\" la página ya está completamente renderizada.\n\n## Manejando Analytics y Efectos Secundarios\n\nLa trampa más grande en producción con prerender son los efectos secundarios. Las páginas pre-renderizadas ejecutan JavaScript. Si tu analytics dispara ` page_view ` durante el prerender, se va a contar doble.\n\nChrome provee la propiedad ` document.prerendering ` y el evento ` prerenderingchange `:\n\n```javascript\nfunction trackPageView() {\n if (document.prerendering) {\n document.addEventListener('prerenderingchange', () => {\n sendPageView();\n }, { once: true });\n } else {\n sendPageView();\n }\n}\n\nfunction sendPageView() {\n const activationStart = performance.getEntriesByType('navigation')[0]?.activationStart || 0;\n\n gtag('event', 'page_view', {\n page_location: window.location.href,\n page_title: document.title,\n prerendered: activationStart > 0,\n activation_delay_ms: activationStart > 0\n ? Math.round(performance.now() - activationStart)\n : 0,\n });\n}\n\ntrackPageView();\n```\n\n## Core Web Vitals: El Impacto Medido\n\nCorrí un experimento controlado en un sitio de contenido con ~200.000 visitantes mensuales. Dos semanas sin speculation rules (control), dos semanas con (experimento). Datos CrUX:\n\n### Período Control (sin especulación):\n\n| Métrica | p75 | Good (%) |\n| --- | --- | --- |\n| LCP | 2.1s | 72% |\n| INP | 180ms | 85% |\n| CLS | 0.04 | 94% |\n\n### Período Experimento (speculation rules, eagerness moderate):\n\n| Métrica | p75 | Good (%) |\n| --- | --- | --- |\n| LCP | 0.8s | 94% |\n| INP | 95ms | 96% |\n| CLS | 0.02 | 97% |\n\nLCP bajó de 2.1s a 0.8s en el percentil 75. No es un error de tipeo. Cuando una página está pre-renderizada, la \"navegación\" es esencialmente swapear un tab oculto al frente. El elemento LCP ya está pintado.\n\nINP mejoró de 180ms a 95ms. Esta me sorprendió. La mejora viene del hecho de que las páginas pre-renderizadas ya completaron el parsing y ejecución inicial de JavaScript. Los event handlers ya están registrados. El main thread está idle cuando el usuario llega.\n\nEl costo de ancho de banda fue medible pero razonable: ~15% de aumento en transferencia total de datos por sesión. En promedio, pre-renderizamos 2.3 páginas por sesión, de las cuales 1.6 fueron efectivamente visitadas (68% hit rate).\n\n## Optimización de INP: La Conexión con Prerender\n\nINP (Interaction to Next Paint) mide el tiempo desde una interacción del usuario hasta el siguiente update visual. En una navegación tradicional, la primera interacción en una nueva página frecuentemente tiene INP elevado porque el browser todavía está parseando JavaScript y el main thread está ocupado.\n\nCon prerender, todo eso pasa durante la fase oculta de prerender. Para cuando el usuario interactúa con la página activada, el main thread está idle y los event handlers están registrados.\n\nResultados de INP de primera interacción:\n\n- **Sin prerender**: Mediana 142ms, p75 215ms, p95 380ms\n- **Con prerender**: Mediana 48ms, p75 82ms, p95 140ms\n\nLa mejora del p95 de 380ms a 140ms es significativa. Ese es case es de cola son típicamente causados por páginas con inicialización pesada de JavaScript que bloquea el main thread durante la ventana de primera interacción. Prerender elimina esa clase entera de regresión de INP.\n\n## Implementación para Diferentes Frameworks\n\nPara Next.js, agregar speculation rules en tu layout:\n\n```jsx\n// app/layout.js\nexport default function RootLayout({ children }) {\n return (\n <html>\n <head>\n <script\n type=\"speculationrules\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify({\n prerender: [{\n where: {\n and: [\n { href_matches: \"/*\" },\n { not: { href_matches: \"/api/*\" } },\n { not: { href_matches: \"/auth/*\" } },\n ],\n },\n eagerness: \"moderate\",\n }],\n }),\n }}\n />\n </head>\n <body>{children}</body>\n </html>\n );\n}\n```\n\nLa Speculation Rules API es la mayor mejora individual que hice al rendimiento de navegación percibido en años. La implementación es directa, un blob JSON en tu HTML. El impacto es inmediato y medible en datos CrUX dentro de 28 días. Las trampas con analytics y efectos secundarios son manejables con la API ` document.prerendering `.\n\nSi te importan los Core Web Vitals, y si se está leyendo esto, probablemente sí, esto debería estar en tu lista de implementación este trimestre. La mejora de LCP sola vale el esfuerzo. La mejora de INP es el bonus que lo hace transformador.\n\n## Preguntas frecuentes\n\n### La Speculation Rules API funciona en todos los browsers?\n\nNo. A principios de 2026, el soporte completo de prerender solo está en browsers basados en Chromium (Chrome, Edge, Opera). Safari y Firefox soportan la parte de prefetch pero no el prerender completo. La API está diseñada como progressive enhancement, los browsers que no la soportan simplemente ignoran las speculation rules, y la navegación funciona normalmente.\n\n### Cómo difiere el prerender del viejo link rel=prerender?\n\nEl viejo link rel=prerender fue deprecado porque era un hint binario sin granularidad, el browser pre-renderizaba completamente una URL o nada. La Speculation Rules API agrega document rules (pattern matching), niveles de eagerness, scoring de confianza, y la capacidad de especificar múltiples URLs con diferentes estrategias. También funciona correctamente con la gestión de recurse es del browser, sin consumir memoria excesiva.\n\n### El prerender puede causar problemas con analytics o tracking de ads?\n\nSí, esta es una preocupación real. Las páginas pre-renderizadas ejecutan JavaScript, lo que significa que los scripts de analytics van a disparar durante el prerender. Chrome posterga ciertas APIs (como triggers de Intersection Observer para viewability de ads) hasta que la página se activa realmente, pero no todos los proveedores de analytics manejan esto correctamente. Utilizar document.prerendering y el evento prerenderingchange para gatear llamadas de analytics.\n\n## Tips\n\n1. **LuchoTip:** Comenzar con reglas de ` prefetch ` antes de saltar a ` prerender `. Prefetch solo descarga el documento (típicamente 5-50KB), mientras que prerender descarga y ejecuta todo, stylesheets, scripts, imágenes. En una página con 2MB de assets, un prerender errado cuesta ancho de banda real. Utilizar ` prefetch ` para confianza moderada y ` prerender ` solo para navegaciones de alta confianza.\n2. **LuchoTip:** Siempre colocar ` eagerness: \"moderate\" ` en tus speculation rules en producción en vez de ` \"eager\" `. Eager dispara inmediatamente al cargar la página para todas las URLs que matchean, lo que puede triggear docenas de prerenders simultáneos en páginas con muchos links. Moderate espera intención de hover (umbral de 200ms), que filtra hovers accidentales y ahorra 80% de especulaciones desperdiciadas.\n3. **LuchoTip:** Probar las speculation rules con Chrome DevTools → Application → Speculative loads tab. Muestra qué URLs se están pre-renderizando, su estado, y razones de falla. Encontré reglas de especulación rotas que fallaban silenciosamente porque la página target tenía ` Cache-Control: no-store `, lo que bloquea el prerender completamente.\n\n- speculation-rules\n- prerender\n- prefetch\n- core-web-vitals\n- inp\n- web-performance\n- chrome\n- navigation\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)","headings":[{"level":1,"text":"Speculation Rules API: Pre-renderizado de Páginas Antes de la Navegación e Impacto Medido en Core Web Vitals","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#title"},{"level":2,"text":"La API: Cómo Funciona","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#la-api-cmo-funciona"},{"level":2,"text":"Niveles de Eagerness: El Espectro de Confianza","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#niveles-de-eagerness-el-espectro-de-confianza"},{"level":2,"text":"Speculation Rules Dinámicas","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#speculation-rules-dinmicas"},{"level":2,"text":"Manejando Analytics y Efectos Secundarios","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#manejando-analytics-y-efectos-secundarios"},{"level":2,"text":"Core Web Vitals: El Impacto Medido","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#core-web-vitals-el-impacto-medido"},{"level":3,"text":"Período Control (sin especulación):","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#perodo-control-sin-especulacin"},{"level":3,"text":"Período Experimento (speculation rules, eagerness moderate):","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#perodo-experimento-speculation-rules-eagerness-moderate"},{"level":2,"text":"Optimización de INP: La Conexión con Prerender","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#optimizacin-de-inp-la-conexin-con-prerender"},{"level":2,"text":"Implementación para Diferentes Frameworks","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#implementacin-para-diferentes-frameworks"},{"level":2,"text":"Preguntas frecuentes","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#questions"},{"level":3,"text":"La Speculation Rules API funciona en todos los browsers?","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#question-1"},{"level":3,"text":"Cómo difiere el prerender del viejo link rel=prerender?","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#question-2"},{"level":3,"text":"El prerender puede causar problemas con analytics o tracking de ads?","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#question-3"},{"level":2,"text":"Tips","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#article-tips"}],"sections":[{"heading":"Speculation Rules API: Pre-renderizado de Páginas Antes de la Navegación e Impacto Medido en Core Web Vitals","level":1,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation","content":"Web Performance"},{"heading":"Speculation Rules API: Pre-renderizado de Páginas Antes de la Navegación e Impacto Medido en Core Web Vitals","level":1,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#title","content":"2026-03-057 min lectura\n\nLucio Durán\nEngineering Manager & AI Solutions Architect\n\nTambién disponible en: [English](<https://lucioduran.com/blog/speculation-rules-api-prerender-navigation>)"},{"heading":"La API: Cómo Funciona","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#la-api-cmo-funciona","content":"Las speculation rules se declaran como un objeto JSON dentro de un tag ` <script type=\"speculationrules\"> `:\n\n```html\n<script type=\"speculationrules\">\n{\n \"prerender\": [\n {\n \"where\": {\n \"and\": [\n { \"href_matches\": \"/*\" },\n { \"not\": { \"href_matches\": \"/logout\" } },\n { \"not\": { \"href_matches\": \"/api/*\" } },\n { \"not\": { \"selector_matches\": \".no-prerender\" } }\n ]\n },\n \"eagerness\": \"moderate\"\n }\n ],\n \"prefetch\": [\n {\n \"where\": {\n \"href_matches\": \"/blog/*\"\n },\n \"eagerness\": \"conservative\"\n }\n ]\n}\n</script>\n```\n\nEsto le dice a Chrome: \"Para cualquier link interno que no sea la página de logout o una ruta de API, pre-renderizala cuando el usuario muestre interés moderado (hover por 200ms). Para links del blog, prefetchealos con intención conservadora (pointerdown, el momento del click).\"\n\nLa cláusula ` where ` soporta pattern matching de URLs (` href_matches `) y matching de selectores CSS (` selector_matches `). Puede componer reglas con ` and `, ` or `, y ` not `. Esto es vastamente más poderoso que el viejo ` <link rel=prerender> ` que solo podía apuntar a una sola URL."},{"heading":"Niveles de Eagerness: El Espectro de Confianza","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#niveles-de-eagerness-el-espectro-de-confianza","content":"Hay cuatro niveles de eagerness, cada uno mapeando a una señal diferente de intención del usuario:\n\n| Eagerness | Trigger | Lead Time Típico | Caso de Uso |\n| --- | --- | --- | --- |\n| ` immediate ` | Carga de página | Segundos | Navegación siguiente conocida (paso 2 de wizard) |\n| ` eager ` | Link se hace visible | Segundos | Navegación de alta probabilidad |\n| ` moderate ` | Hover (200ms) | 200-800ms | Links de navegación general |\n| ` conservative ` | Pointerdown/touchstart | 50-200ms | Páginas de menor confianza o costosas |\n\nEn la práctica, ` moderate ` es el punto óptimo para la mayoría de los sitios. Te da 200-800ms de lead time (duración del hover antes del click), que es suficiente para pre-renderizar completamente una página típica.\n\nInstrumenté el comportamiento de hover en un sitio de documentación con 40.000 visitantes diarios:\n\n```javascript\ndocument.querySelectorAll('a[href]').forEach(link => {\n let hoverStart = 0;\n\n link.addEventListener('pointerenter', () => {\n hoverStart = performance.now();\n });\n\n link.addEventListener('click', () => {\n const hoverDuration = performance.now() - hoverStart;\n navigator.sendBeacon('/analytics/hover', JSON.stringify({\n duration: Math.round(hoverDuration),\n url: link.href,\n clicked: true,\n }));\n });\n});\n```\n\nResultados de 2 semanas de datos:\n\n- Mediana de hover-a-click: 380ms\n- Percentil 75: 620ms\n- Percentil 90: 1.100ms\n- Tasa hover-a-click (hover \\> 200ms): 68% de los hovers resultaron en click\n\nCon eagerness ` moderate ` (umbral de 200ms), predecimos correctamente el 68% de las navegaciones. El 32% de prerenders desperdiciados es un costo de ancho de banda, pero Chrome maneja el lifecycle del prerender agresivamente, si la memoria está limitada, desaloja páginas pre-renderizadas."},{"heading":"Speculation Rules Dinámicas","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#speculation-rules-dinmicas","content":"Las reglas estáticas en HTML funcionan para case es simples, pero los sitios reales necesitan reglas dinámicas basadas en comportamiento del usuario, A/B tests, o personalización:\n\n```javascript\nfunction updateSpeculationRules(urls) {\n document.querySelectorAll('script[type=\"speculationrules\"]')\n .forEach(el => el.remove());\n\n const script = document.createElement('script');\n script.type = 'speculationrules';\n script.textContent = JSON.stringify({\n prerender: [{\n urls: urls.highConfidence,\n eagerness: 'moderate',\n }],\n prefetch: [{\n urls: urls.lowConfidence,\n eagerness: 'conservative',\n }],\n });\n document.head.appendChild(script);\n}\n\n// Predecir próxima página basado en profundidad de scroll\nfunction predictNextPage() {\n const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight);\n\n if (scrollPercent > 0.7) {\n const nextLink = document.querySelector('a.pagination-next');\n if (nextLink) {\n updateSpeculationRules({\n highConfidence: [nextLink.href],\n lowConfidence: [],\n });\n }\n }\n}\n\nwindow.addEventListener('scroll', debounce(predictNextPage, 500), { passive: true });\n```\n\nUso este patrón en un blog donde los artículos tienen links de \"próximo post\". Cuando el usuario scrollea más del 70% del artículo, agrego una regla de prerender para el próximo post. Para cuando llegan abajo y hacen click en \"Siguiente,\" la página ya está completamente renderizada."},{"heading":"Manejando Analytics y Efectos Secundarios","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#manejando-analytics-y-efectos-secundarios","content":"La trampa más grande en producción con prerender son los efectos secundarios. Las páginas pre-renderizadas ejecutan JavaScript. Si tu analytics dispara ` page_view ` durante el prerender, se va a contar doble.\n\nChrome provee la propiedad ` document.prerendering ` y el evento ` prerenderingchange `:\n\n```javascript\nfunction trackPageView() {\n if (document.prerendering) {\n document.addEventListener('prerenderingchange', () => {\n sendPageView();\n }, { once: true });\n } else {\n sendPageView();\n }\n}\n\nfunction sendPageView() {\n const activationStart = performance.getEntriesByType('navigation')[0]?.activationStart || 0;\n\n gtag('event', 'page_view', {\n page_location: window.location.href,\n page_title: document.title,\n prerendered: activationStart > 0,\n activation_delay_ms: activationStart > 0\n ? Math.round(performance.now() - activationStart)\n : 0,\n });\n}\n\ntrackPageView();\n```"},{"heading":"Core Web Vitals: El Impacto Medido","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#core-web-vitals-el-impacto-medido","content":"Corrí un experimento controlado en un sitio de contenido con ~200.000 visitantes mensuales. Dos semanas sin speculation rules (control), dos semanas con (experimento). Datos CrUX:"},{"heading":"Período Control (sin especulación):","level":3,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#perodo-control-sin-especulacin","content":"| Métrica | p75 | Good (%) |\n| --- | --- | --- |\n| LCP | 2.1s | 72% |\n| INP | 180ms | 85% |\n| CLS | 0.04 | 94% |"},{"heading":"Período Experimento (speculation rules, eagerness moderate):","level":3,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#perodo-experimento-speculation-rules-eagerness-moderate","content":"| Métrica | p75 | Good (%) |\n| --- | --- | --- |\n| LCP | 0.8s | 94% |\n| INP | 95ms | 96% |\n| CLS | 0.02 | 97% |\n\nLCP bajó de 2.1s a 0.8s en el percentil 75. No es un error de tipeo. Cuando una página está pre-renderizada, la \"navegación\" es esencialmente swapear un tab oculto al frente. El elemento LCP ya está pintado.\n\nINP mejoró de 180ms a 95ms. Esta me sorprendió. La mejora viene del hecho de que las páginas pre-renderizadas ya completaron el parsing y ejecución inicial de JavaScript. Los event handlers ya están registrados. El main thread está idle cuando el usuario llega.\n\nEl costo de ancho de banda fue medible pero razonable: ~15% de aumento en transferencia total de datos por sesión. En promedio, pre-renderizamos 2.3 páginas por sesión, de las cuales 1.6 fueron efectivamente visitadas (68% hit rate)."},{"heading":"Optimización de INP: La Conexión con Prerender","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#optimizacin-de-inp-la-conexin-con-prerender","content":"INP (Interaction to Next Paint) mide el tiempo desde una interacción del usuario hasta el siguiente update visual. En una navegación tradicional, la primera interacción en una nueva página frecuentemente tiene INP elevado porque el browser todavía está parseando JavaScript y el main thread está ocupado.\n\nCon prerender, todo eso pasa durante la fase oculta de prerender. Para cuando el usuario interactúa con la página activada, el main thread está idle y los event handlers están registrados.\n\nResultados de INP de primera interacción:\n\n- **Sin prerender**: Mediana 142ms, p75 215ms, p95 380ms\n- **Con prerender**: Mediana 48ms, p75 82ms, p95 140ms\n\nLa mejora del p95 de 380ms a 140ms es significativa. Ese es case es de cola son típicamente causados por páginas con inicialización pesada de JavaScript que bloquea el main thread durante la ventana de primera interacción. Prerender elimina esa clase entera de regresión de INP."},{"heading":"Implementación para Diferentes Frameworks","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#implementacin-para-diferentes-frameworks","content":"Para Next.js, agregar speculation rules en tu layout:\n\n```jsx\n// app/layout.js\nexport default function RootLayout({ children }) {\n return (\n <html>\n <head>\n <script\n type=\"speculationrules\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify({\n prerender: [{\n where: {\n and: [\n { href_matches: \"/*\" },\n { not: { href_matches: \"/api/*\" } },\n { not: { href_matches: \"/auth/*\" } },\n ],\n },\n eagerness: \"moderate\",\n }],\n }),\n }}\n />\n </head>\n <body>{children}</body>\n </html>\n );\n}\n```\n\nLa Speculation Rules API es la mayor mejora individual que hice al rendimiento de navegación percibido en años. La implementación es directa, un blob JSON en tu HTML. El impacto es inmediato y medible en datos CrUX dentro de 28 días. Las trampas con analytics y efectos secundarios son manejables con la API ` document.prerendering `.\n\nSi te importan los Core Web Vitals, y si se está leyendo esto, probablemente sí, esto debería estar en tu lista de implementación este trimestre. La mejora de LCP sola vale el esfuerzo. La mejora de INP es el bonus que lo hace transformador."},{"heading":"Preguntas frecuentes","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#questions","content":""},{"heading":"La Speculation Rules API funciona en todos los browsers?","level":3,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#question-1","content":"No. A principios de 2026, el soporte completo de prerender solo está en browsers basados en Chromium (Chrome, Edge, Opera). Safari y Firefox soportan la parte de prefetch pero no el prerender completo. La API está diseñada como progressive enhancement, los browsers que no la soportan simplemente ignoran las speculation rules, y la navegación funciona normalmente."},{"heading":"Cómo difiere el prerender del viejo link rel=prerender?","level":3,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#question-2","content":"El viejo link rel=prerender fue deprecado porque era un hint binario sin granularidad, el browser pre-renderizaba completamente una URL o nada. La Speculation Rules API agrega document rules (pattern matching), niveles de eagerness, scoring de confianza, y la capacidad de especificar múltiples URLs con diferentes estrategias. También funciona correctamente con la gestión de recurse es del browser, sin consumir memoria excesiva."},{"heading":"El prerender puede causar problemas con analytics o tracking de ads?","level":3,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#question-3","content":"Sí, esta es una preocupación real. Las páginas pre-renderizadas ejecutan JavaScript, lo que significa que los scripts de analytics van a disparar durante el prerender. Chrome posterga ciertas APIs (como triggers de Intersection Observer para viewability de ads) hasta que la página se activa realmente, pero no todos los proveedores de analytics manejan esto correctamente. Utilizar document.prerendering y el evento prerenderingchange para gatear llamadas de analytics."},{"heading":"Tips","level":2,"url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#article-tips","content":"1. **LuchoTip:** Comenzar con reglas de ` prefetch ` antes de saltar a ` prerender `. Prefetch solo descarga el documento (típicamente 5-50KB), mientras que prerender descarga y ejecuta todo, stylesheets, scripts, imágenes. En una página con 2MB de assets, un prerender errado cuesta ancho de banda real. Utilizar ` prefetch ` para confianza moderada y ` prerender ` solo para navegaciones de alta confianza.\n2. **LuchoTip:** Siempre colocar ` eagerness: \"moderate\" ` en tus speculation rules en producción en vez de ` \"eager\" `. Eager dispara inmediatamente al cargar la página para todas las URLs que matchean, lo que puede triggear docenas de prerenders simultáneos en páginas con muchos links. Moderate espera intención de hover (umbral de 200ms), que filtra hovers accidentales y ahorra 80% de especulaciones desperdiciadas.\n3. **LuchoTip:** Probar las speculation rules con Chrome DevTools → Application → Speculative loads tab. Muestra qué URLs se están pre-renderizando, su estado, y razones de falla. Encontré reglas de especulación rotas que fallaban silenciosamente porque la página target tenía ` Cache-Control: no-store `, lo que bloquea el prerender completamente.\n\n- speculation-rules\n- prerender\n- prefetch\n- core-web-vitals\n- inp\n- web-performance\n- chrome\n- navigation\n\n[Volver al Blog](<https://lucioduran.com/es/blog>)"}],"links":[{"text":"English","url":"https://lucioduran.com/blog/speculation-rules-api-prerender-navigation"},{"text":"Volver al Blog","url":"https://lucioduran.com/es/blog"}],"structuredData":[{"@context":"https://schema.org","@graph":[{"@type":"BlogPosting","@id":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation#article","mainEntityOfPage":{"@type":"WebPage","@id":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation"},"headline":"Speculation Rules API: Pre-renderizado de Páginas Antes de la Navegación e Impacto Medido en Core Web Vitals","description":"Un análisis técnico de la Speculation Rules API para prerender y prefetch, estrategias de especulación basadas en confianza, detalles de implementación en Chrome, y mejoras medibles en Core Web Vitals incluyendo optimización de INP.","datePublished":"2026-03-05","author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"publisher":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"image":"https://lucioduran.com/favicons/og-default.png","url":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation","inLanguage":"es","isPartOf":{"@id":"https://lucioduran.com/blog#blog"},"articleSection":"Web Performance","keywords":"speculation-rules, prerender, prefetch, core-web-vitals, inp, web-performance, chrome, navigation","wordCount":1142,"timeRequired":"PT7M","workTranslation":[{"@type":"BlogPosting","inLanguage":"en","url":"https://lucioduran.com/blog/speculation-rules-api-prerender-navigation"}]},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Inicio","item":"https://lucioduran.com/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://lucioduran.com/es/blog"},{"@type":"ListItem","position":3,"name":"Speculation Rules API: Pre-renderizado de Páginas Antes de la Navegación e Impacto Medido en Core Web Vitals","item":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation"}]},{"@type":"FAQPage","mainEntity":[{"@type":"Question","name":"La Speculation Rules API funciona en todos los browsers?","acceptedAnswer":{"@type":"Answer","text":"No. A principios de 2026, el soporte completo de prerender solo está en browsers basados en Chromium (Chrome, Edge, Opera). Safari y Firefox soportan la parte de prefetch pero no el prerender completo. La API está diseñada como progressive enhancement, los browsers que no la soportan simplemente ignoran las speculation rules, y la navegación funciona normalmente."}},{"@type":"Question","name":"Cómo difiere el prerender del viejo link rel=prerender?","acceptedAnswer":{"@type":"Answer","text":"El viejo link rel=prerender fue deprecado porque era un hint binario sin granularidad, el browser pre-renderizaba completamente una URL o nada. La Speculation Rules API agrega document rules (pattern matching), niveles de eagerness, scoring de confianza, y la capacidad de especificar múltiples URLs con diferentes estrategias. También funciona correctamente con la gestión de recurse es del browser, sin consumir memoria excesiva."}},{"@type":"Question","name":"El prerender puede causar problemas con analytics o tracking de ads?","acceptedAnswer":{"@type":"Answer","text":"Sí, esta es una preocupación real. Las páginas pre-renderizadas ejecutan JavaScript, lo que significa que los scripts de analytics van a disparar durante el prerender. Chrome posterga ciertas APIs (como triggers de Intersection Observer para viewability de ads) hasta que la página se activa realmente, pero no todos los proveedores de analytics manejan esto correctamente. Utilizar document.prerendering y el evento prerenderingchange para gatear llamadas de analytics."}}]}]}],"contentHash":"8e2d279a2dbd2418cd67e4259bac862ce04aeaece6a77abbdc7f511388d363c1","provenance":{"method":"Deterministic serialization of the server-rendered main element","source":"https://lucioduran.com/es/blog/speculation-rules-api-prerender-navigation","hashAlgorithm":"sha256","hashScope":"JSON document fields before contentHash and provenance","sourceHTMLBytes":64900,"contentBytes":11917}}
