El INP (Interaction to Next Paint) es el Core Web Vital más reciente y el más difícil de optimizar. Desde marzo de 2024 reemplazó al FID como métrica oficial de interactividad. Mientras el FID solo medía el delay antes del primer clic, el INP mide la latencia de respuesta de todas las interacciones del usuario durante su visita completa: clics, pulsaciones de teclado y taps. Un INP malo hace que la página se sienta lenta y torpe aunque cargue rápido.
¿Cómo se calcula el INP exactamente?
Para cada interacción del usuario, el navegador mide el tiempo entre el evento de entrada (clic, tecla, tap) y el siguiente frame pintado en pantalla. El INP reportado es el percentil 98 de todas las interacciones de la sesión — es decir, descarta el 2% peor para evitar que un outlier puntual arruine la métrica, pero sí penaliza interacciones consistentemente lentas.
| Umbral INP | Calificación | Experiencia |
|---|---|---|
| ≤ 200 ms | ✅ Bueno | Respuesta percibida como instantánea |
| 200 – 500 ms | ⚠️ Necesita mejora | Lag perceptible, experiencia degradada |
| > 500 ms | ❌ Malo | Página percibida como bloqueada o rota |
INP se mide con datos de campo reales (CrUX), no solo en laboratorio. Esto significa que PageSpeed Insights puede mostrar un INP estimado diferente al que Google usa para el ranking, que proviene de los datos reales de usuarios de Chrome. Si tu página tiene poco tráfico, puede no haber suficientes datos de campo y Google usa solo el dato de laboratorio.
La causa raíz del INP alto: el hilo principal bloqueado
El INP alto casi siempre tiene la misma causa raíz: el hilo principal (main thread) del navegador está ocupado procesando JavaScript cuando el usuario interactúa. El navegador es de un solo hilo — no puede procesar eventos de usuario y ejecutar JavaScript al mismo tiempo. Si hay una tarea larga (long task, > 50ms) ejecutándose cuando el usuario hace clic, la respuesta se retrasa hasta que esa tarea termina.
Causa 1: Tareas largas de JavaScript (Long Tasks)
Una long task es cualquier tarea que bloquea el hilo principal durante más de 50ms. El usuario percibe el lag cuando la long task ocurre justo cuando intenta interactuar. Cuanto más larga la tarea, peor el INP.
- •Identifica las long tasks con Chrome DevTools → Performance → graba mientras interactúas. Las tareas largas aparecen como bloques rojos en el timeline.
- •Divide las long tasks usando scheduler.yield() o setTimeout(fn, 0) para ceder el control al navegador entre fragmentos de trabajo.
- •Prioriza qué JavaScript se ejecuta en el hilo principal — mueve el trabajo no urgente a Web Workers.
// Técnica: dividir una tarea larga con scheduler.yield()
async function procesarListaLarga(items) {
for (let i = 0; i < items.length; i++) {
procesarItem(items[i])
// Cede el control al navegador cada 50 items
// para que pueda procesar interacciones de usuario
if (i % 50 === 0) {
await scheduler.yield()
// o: await new Promise(resolve => setTimeout(resolve, 0))
}
}
}Causa 2: Event handlers costosos
El trabajo que ejecuta el event handler (la función que responde al clic o tecla) consume parte del tiempo de INP. Si el handler hace operaciones costosas — consultas DOM complejas, cálculos pesados, re-renders grandes — el INP aumenta.
- •Mueve el trabajo no urgente fuera del event handler usando requestAnimationFrame o setTimeout — ejecuta primero lo visible, aplaza lo demás.
- •Evita leer y escribir el DOM de forma intercalada en el mismo handler (layout thrashing).
- •Usa debounce o throttle en handlers que responden a eventos frecuentes (scroll, resize, input).
// Incorrecto: todo el trabajo en el handler bloquea la respuesta
button.addEventListener('click', () => {
const data = calcularDatosComplejos() // tarea costosa
actualizarUI(data)
enviarAnalytics(data) // no urgente
})
// Correcto: aplaza el trabajo no urgente
button.addEventListener('click', () => {
// Trabajo urgente: actualizar UI inmediatamente
actualizarUIRapido()
// Trabajo no urgente: aplazar tras el próximo frame
requestAnimationFrame(() => {
const data = calcularDatosComplejos()
actualizarUICompleta(data)
setTimeout(() => enviarAnalytics(data), 0)
})
})Causa 3: Renders costosos en frameworks SPA (React, Vue, Angular)
En aplicaciones React, Vue o Angular, una interacción puede disparar un re-render de un árbol de componentes grande. Si el render es costoso, el INP sube. Este es el problema más frecuente en SPAs con mucho estado compartido.
- •En React: usa React.memo, useMemo y useCallback para evitar re-renders innecesarios de componentes que no han cambiado.
- •Aplaza los re-renders no urgentes con useTransition o startTransition — React procesa la actualización sin bloquear las interacciones del usuario.
- •Divide componentes grandes en piezas más pequeñas para que los re-renders sean más granulares.
- •En Vue: usa computed properties con cuidado y evita watchers que disparan efectos en cascada.
// React: usa startTransition para aplazar renders no urgentes
import { startTransition, useState } from 'react'
function BuscadorProductos() {
const [query, setQuery] = useState('')
const [resultados, setResultados] = useState([])
const handleInput = (e) => {
// Actualización urgente: mostrar lo que escribe el usuario
setQuery(e.target.value)
// Actualización no urgente: buscar y renderizar resultados
startTransition(() => {
setResultados(buscarProductos(e.target.value))
})
}
return <input value={query} onChange={handleInput} />
}Causa 4: Scripts de terceros que bloquean el hilo principal
Los scripts de terceros (analytics, chat widgets, A/B testing, mapas, social buttons) compiten con tu código por el hilo principal. Un script de terceros que ejecuta código pesado puede incrementar el INP de páginas que de otra forma serían interactivas.
- •Carga los scripts de terceros con defer o async para que no bloqueen el renderizado inicial.
- •Usa el atributo loading="lazy" o la Intersection Observer API para cargar scripts de terceros solo cuando el usuario los necesita (por ejemplo, el chat solo cuando hace scroll hasta el footer).
- •Audita qué scripts de terceros tienes activos con el panel de Coverage en Chrome DevTools y elimina los que no son imprescindibles.
- •Considera cargar Google Tag Manager en modo condicional — muchos tags de GTM se pueden cargar después de la primera interacción del usuario.
Cómo diagnosticar el INP de tu sitio
El Monitor Core Web Vitals de iRankly te muestra el INP actual de cada URL usando los datos de PageSpeed Insights. Identifica qué páginas tienen INP en rango "Necesita mejora" o "Malo" para priorizar la optimización.
Prueba la herramienta gratis
Analiza tus URLs con Monitor Core Web Vitals de iRankly. Sin registro, sin tarjeta.
Para un diagnóstico más profundo, instala la extensión Web Vitals de Chrome y navega por tu sitio interactuando con los elementos — haz clics, abre menús, usa formularios. La extensión muestra el INP en tiempo real e identifica qué interacción concreta está causando la latencia más alta.
El INP alto suele estar concentrado en páginas o interacciones específicas, no en todo el sitio. Antes de optimizar de forma global, identifica las 3-5 interacciones con mayor latencia y céntrate en ellas — el impacto será mucho mayor con menos esfuerzo.
Las otras dos métricas, y por qué el laboratorio no mide INP: