Back

Interaction to Next Paint (INP): La Guía Definitiva de Optimización (2025)

En marzo de 2024, Google reemplazó oficialmente First Input Delay (FID) con Interaction to Next Paint (INP) como una Core Web Vital. No fue solo un cambio de métricas; fue un cambio fundamental en cómo medimos la capacidad de respuesta de la web.

Durante años, los desarrolladores optimizaron para el primer clic. Pero los usuarios no hacen clic una sola vez. Escriben, alternan, arrastran y esperan que la interfaz responda instantáneamente cada vez. FID solo medía la primera impresión. INP mide toda la relación.

Si has notado que tu "Total Blocking Time" (TBT) es alto, o tu puntuación de Lighthouse es verde pero tus usuarios reales se quejan de una UI "lenta", esta guía es para ti. Vamos a profundizar en la mecánica del hilo principal (main thread) del navegador para entender por qué las interacciones se retrasan y cómo solucionarlo.

La Anatomía de una Interacción

Para optimizar INP, debes entender qué sucede cuando un usuario hace clic en un botón. No es instantáneo. El navegador pasa por tres fases distintas:

  1. Input Delay (Retraso de Entrada): El tiempo desde que el usuario toca hasta que el navegador comienza a ejecutar el manejador de eventos. A menudo causado porque el hilo principal está bloqueado por otras tareas (ej. un proceso de hidratación corriendo justo cuando el usuario hace clic).
  2. Processing Time (Tiempo de Procesamiento): El tiempo que toma ejecutar tus callbacks de eventos (actualizaciones de estado de React, manipulación del DOM, lógica compleja).
  3. Presentation Delay (Retraso de Presentación): El tiempo desde que tu código termina de ejecutarse hasta que el navegador realmente pinta el siguiente frame en la pantalla.

INP = Input Delay + Processing Time + Presentation Delay

La mayoría de los desarrolladores se enfocan solo en el paso 2 (optimizar su código). Sin embargo, una gran parte de las malas puntuaciones de INP provienen de los pasos 1 y 3.

Por qué console.time() Te Miente

Podrías envolver tu manejador de clics en un console.time() y ver que se ejecuta en 20ms. "¡Genial!", piensas, "Mi código es rápido". Pero tu puntuación INP reporta 400ms. ¿Por qué?

Porque console.time() solo mide la ejecución de JavaScript. No mide el costo de renderizado.

Si tu actualización de estado de React de 20ms desencadena un re-renderizado de todo el árbol de componentes, forzando al navegador a recalcular estilos y layout para 5,000 nodos DOM, ese "layout thrashing" ocurre después de que tu JavaScript termina pero antes del siguiente pintado. Eso es Presentation Delay, y cuenta en tu contra para el INP.

Estrategia 1: Ceder el Control al Hilo Principal (Yielding)

La regla de oro de la capacidad de respuesta es: No acapares el hilo principal.

Si tienes una tarea de larga duración (ej. procesar un array grande de datos), el navegador se "congela". No puede manejar nuevas entradas ni pintar la pantalla. La solución es dividir las tareas largas en trozos más pequeños y "ceder" (yield) el control al navegador entre ellos.

La Vieja Escuela: setTimeout

function processData(items) { if (items.length === 0) return; // Procesar un ítem doHeavyWork(items[0]); // Programar el resto para después setTimeout(() => { processData(items.slice(1)); }, 0); }

Esto funciona, pero setTimeout tiene un retraso mínimo (a menudo 4ms o más) y no prioriza las tareas inteligentemente.

La Forma Moderna: scheduler.yield()

La nueva API scheduler.yield() (actualmente en origin trial o con polyfill) te permite ceder al hilo principal e inmediatamente reanudar la ejecución sin la penalización de setTimeout.

async function processData(items) { for (const item of items) { doHeavyWork(item); // Ceder al hilo principal para dejar que el navegador maneje inputs/pintado // ¡Esto verifica si hay input de usuario pendiente! await scheduler.yield(); } }

Esto cambia las reglas del juego. Le dice al navegador: "Voy a pausar un microsegundo. Si hay un clic esperando, manéjalo ahora. Si no, seguiré".

Estrategia 2: Optimizar el Presentation Delay

Si tu JavaScript es rápido pero el pintado es lento, tienes un problema de renderizado.

  1. Reducir el Tamaño del DOM: Un árbol DOM masivo aumenta el costo del Recálculo de Estilos y Layout. Virtualiza listas largas.
  2. CSS Containment: Usa la propiedad content-visibility: auto para saltar el renderizado de contenido fuera de pantalla.
  3. Evitar Layout Thrashing: No leas propiedades de layout (como offsetHeight) inmediatamente después de escribirlas. Esto fuerza al navegador a realizar un cálculo de layout síncrono.

Estrategia 3: Feedback Inmediato (UI Optimista)

Psicológicamente, un usuario siente que una app es "lenta" si no ve una reacción. Técnicamente, INP mide el tiempo hasta el siguiente pintado.

Si tienes una operación pesada (como una llamada a API), pinta algo inmediatamente.

Mal Patrón:

button.addEventListener('click', async () => { const data = await fetchData(); // Espera a la red... renderData(data); // ...luego pinta. });

¡El INP incluye el tiempo de espera de la red!

Buen Patrón:

button.addEventListener('click', () => { showSpinner(); // ¡Pinta inmediatamente! INP deja de medir aquí. fetchData().then(data => { renderData(data); hideSpinner(); }); });

Al mostrar un spinner o un estado activo inmediatamente, "completas" la interacción desde la perspectiva del navegador. La solicitud de red subsiguiente y el renderizado final son tareas separadas que no dañan tu puntuación INP.

Conclusión

INP es una métrica estricta, pero nos obliga a construir mejor software. Nos empuja lejos de arquitecturas "pesadas en JS que bloquean el hilo principal" hacia diseños "asíncronos, que ceden el control y responden".

Empieza perfilando tus interacciones más lentas. ¿Es la lógica? ¿El renderizado? ¿O simplemente un hilo principal ocupado? Una vez que identifiques el cuello de botella, las herramientas—scheduler.yield(), virtualización del DOM y actualizaciones de UI optimistas—están listas para que las uses.

Haz que tu sitio se sienta instantáneo. Tus usuarios (y tus rankings SEO) te lo agradecerán.

Web PerformanceCore Web VitalsJavaScriptOptimizationINP

Explora herramientas relacionadas

Prueba estas herramientas gratuitas de Pockit