¿Qué mide INP?
Interaction to Next Paint es la métrica de responsividad de Core Web Vitals que sustituyó oficialmente a FID (First Input Delay) el 12 de marzo de 2024. Mide la latencia del peor evento de interacción durante toda la sesión del usuario en la página: clic, pulsación de tecla, tap táctil. INP se reporta cuando el usuario abandona la página o navega a otra URL.
A diferencia de FID, que solo medía el primer evento, INP mide todos los eventos y reporta el peor (el de mayor latencia). Esto refleja mucho mejor la frustración real del usuario: una página que carga rápido pero se queda colgada al tercer clic ya no pasa INP, mientras antes pasaba FID.
Umbrales oficiales
| Bueno | Necesita mejora | Pobre |
|---|---|---|
| ≤ 200 ms | ≤ 500 ms | > 500 ms |
Aplicados al percentil 75 de visitas reales en CrUX. Es decir: el 75 % de las sesiones debe tener su peor interacción en 200 ms o menos.
Componentes del tiempo INP
INP mide desde que el usuario inicia la interacción (mousedown, keydown, touchstart) hasta que el navegador pinta el siguiente frame que refleja el resultado. Incluye:
- Input delay: tiempo bloqueado por código JavaScript en ejecución cuando llega el evento.
- Processing time: tiempo del handler del evento (callbacks, listeners, validaciones).
- Presentation delay: tiempo entre el final del handler y el paint.
Causas frecuentes de INP malo
- Listeners pesados: validar un formulario complejo, ejecutar un cálculo grande, parsear JSON pesado en
onclick. - JavaScript de terceros bloqueante: tags de analytics, banners, chats que monopolizan el hilo principal.
- Long Tasks: cualquier tarea > 50 ms en el main thread bloquea otras interacciones.
- Forced layout / reflow dentro de un handler: leer y escribir
offsetWidth,getBoundingClientRect()en bucle. - Re-renderizado innecesario en frameworks (React, Vue) que recalculan árboles enteros por un cambio puntual.
Optimizaciones típicas
requestIdleCallbackoscheduler.yieldpara diferir trabajo no crítico.- Code splitting: cargar solo el JS que la interacción necesita.
- Debouncing y throttling en handlers de scroll/resize/input.
- Web Workers para tareas pesadas fuera del main thread.
- Reducir JS de terceros: cada script externo es un riesgo INP que no controlas.
- Optimizar React/Vue:
useMemo,useCallback,React.memo, evitar re-renders en cascada.
Diferencias clave con FID
| Aspecto | FID (retirado) | INP (vigente) |
|---|---|---|
| Eventos | Solo el primero | Todos los de la sesión |
| Cuándo se reporta | Al primer input | Al unload de la página |
| Refleja | Carga inicial | Experiencia completa |
| Umbral bueno | ≤ 100 ms | ≤ 200 ms |
INP es 2× más exigente en umbral pero también más realista. Muchos sitios que tenían FID excelente fallan en INP cuando el usuario interactúa repetidamente.
Cómo lo medimos
- PageSpeed Insights: CrUX p75 + Lighthouse lab (INP en lab es estimación).
- Chrome DevTools Performance: trace con la lista de eventos lentos.
- web-vitals.js: medición en producción con la
attribution buildque indica el listener específico que causa el problema.
En smedialab.es mantenemos INP por debajo de 100 ms al ser un sitio mayoritariamente estático (Astro SSG) con poco JS interactivo. En clientes con sitios complejos (diseño web, e-commerce, dashboards), INP es la métrica que más tarda en cumplirse y la que más esfuerzo requiere.