INP (Interaction to Next Paint) mide la capacidad de respuesta de una página web a las interacciones del usuario. Este artículo desmitifica la métrica de Core Web Vitals de Google, explora cómo se diferencia de la métrica FID (obsoleta) y describe cómo optimizar las rutas de ejecución de JavaScript para lograr puntuaciones “Buenas”.
1. ¿Qué es Interaction to Next Paint (INP)?
INP rastrea la latencia de todas las interacciones del usuario (clics, toques y entradas de teclado) durante la visita a una página. Mide la duración entre que un usuario inicia una acción y el navegador pinta el siguiente fotograma mostrando la actualización visual.
Cómo se diferencia de FID (First Input Delay)
FID era la métrica de respuesta anterior de Google, pero tenía limitaciones que facilitaban su evasión:
- Sesgo de primera interacción: FID solo monitoreaba la primera interacción del usuario. Cualquier retraso posterior causado por navegar menús o hacer clic en filtros se ignoraba.
- Ignoraba la ejecución de scripts: FID solo calculaba el retraso de entrada (cuánto tardaba el navegador en recibir el evento). Ignoraba el tiempo requerido para ejecutar el manejador de eventos de JavaScript y pintar la UI actualizada.
INP aborda estas limitaciones rastreando todas las interacciones durante todo el ciclo de vida de la sesión, reportando la interacción de peor rendimiento (excluyendo valores atípicos).
Umbrales de puntuación INP
- Bueno (Aprobado): 200ms o menos
- Necesita mejora: 200ms a 500ms
- Malo: Más de 500ms
2. Causas principales de puntuaciones INP pobres
El culpable principal detrás de las puntuaciones INP pobres es el Bloqueo del Hilo Principal (Main Thread Blocking).
Debido a que los navegadores manejan el renderizado de la UI y la ejecución de JavaScript en un solo hilo principal, lanzar lógica de script compleja bloquea instantáneamente la actualización del viewport. Si un clic desencadena una tarea que toma 300ms, la pantalla se congela durante esa ventana, elevando tu puntuación INP.
3. Técnicas para optimizar INP
1) Ceder la tarea (dividir tareas largas)
Cualquier función de JavaScript que se ejecute durante más de 50ms se marca como “Tarea larga”. Para resolver esto, divide las tareas de larga duración en pasos modulares y cede el hilo principal al navegador para procesar fotogramas de la UI.
// ✕ Mal: Bucle continuo bloqueando el hilo principal
function processArray(items) {
for (let item of items) {
calculateComplexResult(item); // Congela el navegador
}
}
// ◯ Bien: Ceder el control periódicamente usando async timeouts
async function processArrayOptimized(items) {
for (let i = 0; i < items.length; i++) {
calculateComplexResult(items[i]);
// Ceder cada 50 elementos para permitir que el navegador pinte
if (i % 50 === 0) {
await yieldToMainThread();
}
}
}
function yieldToMainThread() {
// Usar scheduler.yield si es compatible, si no, recurrir a setTimeout
if ('scheduler' in window && 'yield' in window.scheduler) {
return window.scheduler.yield();
}
return new Promise(resolve => setTimeout(resolve, 0));
}
2) Optimizar el bucle de retroalimentación del usuario
Si debes ejecutar lógica pesada, asegúrate de actualizar la UI con un “indicador de carga” o estado de botón activo antes de que comience el script de procesamiento pesado.
button.addEventListener('click', () => {
// Paso 1: Actualizar la UI inmediatamente (registra baja latencia INP)
toggleSpinner(true);
// Paso 2: Poner en cola la tarea de cálculo pesado para el siguiente bucle de eventos
setTimeout(() => {
executeHeavyCalculation();
toggleSpinner(false);
}, 0);
});
4. Conclusión
Optimizar para INP no se trata solo de marcar auditorías de SEO. Proporcionar retroalimentación visual inmediata en las entradas del usuario aumenta las tasas de conversión y evita que los usuarios abandonen páginas que no responden. Usa el panel “Rendimiento” de Chrome DevTools para rastrear tareas largas y optimizar tus experiencias de usuario.

