Retraso de entrada del INP: causas, diagnóstico y soluciones

Aprende a encontrar y solucionar los problemas del INP causados por retrasos de entrada.

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-04

Problemas del Interaction to Next Paint (INP) causados por el retraso de entrada

Esta página forma parte de nuestra serie sobre el Interaction to Next Paint (INP). El INP mide el tiempo total desde una interacción del usuario hasta la siguiente actualización visual. El retraso de entrada es la primera de las tres fases que componen el INP, seguida del tiempo de procesamiento y el retraso de presentación. Si no conoces el INP, lee primero nuestra guía sobre cómo identificar y solucionar problemas del INP.

CONSEJO SOBRE EL INP: la mayoría de las veces el retraso de entrada ocurre durante las primeras etapas de carga de la página. En este momento el navegador está más ocupado analizando y ejecutando scripts.

¿Qué es el retraso de entrada?

inp input delay schema

El retraso de entrada es el tiempo que tarda el navegador en empezar a procesar el callback de un evento tras la interacción del usuario con la página (por ejemplo, al hacer clic en un botón o pulsar una tecla). Aunque siempre hay cierto retraso de entrada (incluso los navegadores necesitan tiempo para programar los callbacks), un retraso excesivo ocurre cuando el navegador está ocupado con otras tareas programadas. En este caso no puede programar inmediatamente los callbacks que requiere la interacción.

Durante el retraso de entrada, el usuario ya ha realizado su acción (clic, toque o pulsación de tecla), pero el navegador aún no ha empezado a ejecutar el manejador del evento. El usuario no ve ninguna respuesta. Esto es distinto al tiempo de procesamiento, donde el manejador de eventos se está ejecutando activamente. También es distinto al retraso de presentación, donde el navegador está renderizando la actualización visual. El retraso de entrada es puro tiempo de espera causado por un main thread congestionado.

El retraso de entrada y el INP

El Interaction to Next Paint (INP) se divide en 3 subpartes: "Retraso de entrada", "Tiempo de procesamiento" y "Retraso de presentación".

inp 3 stage input delay highlighted

Quizá notes similitudes de nomenclatura entre el retraso de entrada y la antigua Core Web Vital "First Input Delay" (FID). El Interaction to Next Paint sustituyó al FID como Core Web Vital en marzo de 2024. El First Input Delay solo medía el tiempo entre la primera interacción y el callback del evento. Aunque el FID está retirado, el retraso de entrada sigue siendo importante. Es la base de cada medición del Interaction to Next Paint.

La importancia del retraso de entrada

Muchos desarrolladores piensan en mejorar el INP optimizando las funciones de callback (optimizando el tiempo de procesamiento). Por ello, suelen pasar por alto el retraso de entrada. Es cierto que no suele ser la parte más grande del INP. Sin embargo, si optimizamos el retraso de entrada, a menudo optimizamos todas las interacciones del INP a la vez. Reducir el retraso de entrada mejora cada interacción en la página, no solo la peor.

inp distribution input delay highlighted

En CoreDash recopilamos millones de puntos de datos de las Core Web Vitals cada hora. Según esos datos, el retraso de entrada representa aproximadamente el 18 % del Interaction to Next Paint. Esto es menos que el tiempo de procesamiento o el retraso de presentación. Sin embargo, el retraso de entrada suele ser la fase más fácil de reducir. La causa raíz casi siempre es "demasiado JavaScript ejecutándose en el momento equivocado".

Causas del retraso de entrada

El retraso de entrada ocurre cuando el main thread está ocupado ejecutando otras tareas. Estas tareas pueden originarse por:

inp input delay long task
  1. Tareas tempranas. Los scripts normales, diferidos y asíncronos encolados al principio crean tareas tempranas. Son la fuente más común de retraso de entrada. Se ejecutan durante la ventana crítica de inicio, cuando los usuarios tienen más probabilidades de interactuar con la página.
  2. Tareas programadas. Algunas tareas no se ejecutan al inicio de la carga, sino que se programan para después de que la página haya cargado. Estas tareas también pueden interferir con el INP y causar un retraso de entrada. Por ejemplo, scripts que se ejecutan tras el evento window.onload o scripts retrasados por los supuestos plugins de optimización. Aprende más sobre cuándo usar async vs defer para JavaScript.
  3. Tareas repetitivas. Tareas recurrentes mediante setInterval() que tardan bastante en ejecutarse y coinciden con el INP.
  4. Callbacks solapados. Los callbacks solapados son una causa común de retraso de entrada. Múltiples callbacks programados muy cerca unos de otros pueden crear una cola. Esto retrasa el procesamiento de la siguiente interacción. Por ejemplo, un manejador mouseover que se dispara justo antes de un manejador click puede retrasar el procesamiento del clic durante el tiempo que dure la tarea del mouseover.

Minimiza el retraso de entrada

Para minimizar el retraso de entrada debes asegurar que el navegador no esté ejecutando un (long) task justo antes de que el usuario interactúe con la página. Puedes lograrlo programando las tareas en un momento más adecuado, evitando que duren demasiado o impidiendo las interacciones mientras se ejecutan.
  1. Divide los long tasks tempranos en múltiples tareas más pequeñas. Durante los long tasks el navegador no puede responder a las entradas del usuario. Después de cada tarea corta sí puede. Divide los long tasks con scheduler.yield() o envolviendo cada función en un timeout de 0 con setTimeout(callback, 0).
  2. Gestiona los elementos interactivos. No muestres elementos interactivos (como una barra de búsqueda) antes de que el código JavaScript que los controla esté totalmente cargado. Esto evita clics tempranos en elementos que no están listos para recibirlos. Para optimizar el UX de este patrón, prioriza la carga del JavaScript necesario u oculta/desactiva temporalmente el elemento hasta que sea funcional.
  3. Ejecución de scripts en tiempo de inactividad. Programa los scripts no críticos para que se ejecuten durante los periodos de inactividad del navegador usando requestIdleCallback(). Esta función se ejecuta cuando el navegador está inactivo y no necesita procesar la entrada del usuario.
  4. Usa web workers para ejecutar JavaScript fuera del main thread. Los web workers permiten que los scripts se ejecuten fuera del main thread. Esto evita que el main thread se bloquee y cause problemas de retraso de entrada del INP.
  5. Comprueba si hay entradas pendientes en las tareas repetitivas. Antes de ejecutar un conjunto de tareas programadas, comprueba si hay alguna entrada pendiente. Si la hay, haz yield al main thread primero.
  6. Elimina el código innecesario. Audita tus scripts regularmente y elimina cualquier código innecesario o scripts enteros. Cada línea de código puede causar un retraso de entrada que afecte al Interaction to Next Paint. Consulta nuestra guía sobre 14 métodos para diferir JavaScript para ver técnicas prácticas.

Dividir tareas con scheduler.yield()

La API scheduler.yield() es la forma recomendada de dividir los long tasks. A diferencia de setTimeout(callback, 0), que coloca la continuación al final de la cola de tareas, scheduler.yield() conserva la prioridad de la tarea. Esto significa que el navegador reanudará tu código lo antes posible tras manejar cualquier entrada de usuario pendiente. Aquí tienes una función de ayuda reutilizable:

async function yieldToMain() {
  if ('scheduler' in window && 'yield' in window.scheduler) {
    return await window.scheduler.yield();
  }
  // Fallback para navegadores sin scheduler.yield()
  return new Promise((resolve) => {
    setTimeout(resolve, 0);
  });
}

// Ejemplo: divide una secuencia larga de inicialización
async function initializeApp() {
  loadCriticalFeatures();
  await yieldToMain();  // Deja que el navegador maneje cualquier entrada pendiente

  loadSecondaryFeatures();
  await yieldToMain();

  loadAnalytics();
  await yieldToMain();

  loadNonEssentialWidgets();
}

Para saber más sobre cómo funciona scheduler.yield() a nivel interno, visita el blog de Chrome Developers.

Priorizar tareas con scheduler.postTask()

Mientras que scheduler.yield() divide las tareas, scheduler.postTask() te da un control preciso sobre la prioridad de las mismas. La API acepta tres niveles de prioridad: "user-blocking" para tareas críticas de máxima prioridad, "user-visible" para tareas de prioridad media y "background" para tareas de prioridad mínima que deben ejecutarse durante el tiempo de inactividad.

Con postTask() puedes asegurar que el trabajo no esencial no bloquee las interacciones del usuario. Aquí tienes un ejemplo práctico que programa el trabajo de analítica con prioridad background mientras mantiene las actualizaciones de la UI con la prioridad más alta:

// Prioridad alta: el feedback de la UI se ejecuta primero
scheduler.postTask(() => {
  showLoadingSpinner();
}, { priority: 'user-blocking' });

// Prioridad media: obtener datos
scheduler.postTask(async () => {
  const data = await fetchSearchResults(query);
  renderResults(data);
}, { priority: 'user-visible' });

// Prioridad baja: la analítica puede esperar
scheduler.postTask(() => {
  trackSearchEvent(query);
  sendToAnalytics('search', { query });
}, { priority: 'background' });

Revisa la tabla de compatibilidad de navegadores para scheduler.postTask() antes de usarlo en producción. En navegadores que no soportan la API, usa un fallback hacia requestIdleCallback() para tareas de fondo y queueMicrotask() para tareas de alta prioridad.

Implicaciones prácticas

¿Qué significa esto para tu sitio? Aquí tienes recomendaciones específicas para WordPress y React/Next.js.

WordPress

Por su arquitectura basada en plugins, WordPress suele incluir un tema y muchos plugins. Tanto los plugins como los temas suelen depender de JavaScript para funcionar. Como estos son mantenidos por desarrolladores de terceros, no tienes control sobre sus contenidos. Esto significa que no puedes modificar los archivos ni optimizar el "código malo". Incluso si los scripts se comportan bien hoy, no hay garantía de que lo sigan haciendo tras la próxima actualización.

Para minimizar el retraso de entrada y optimizar el Interaction to Next Paint (INP) en WordPress, sigue estos pasos:

  • Evita usar plugins siempre que sea posible. Aunque los plugins son una forma fácil de añadir funcionalidad, a menudo añaden scripts a la página. Esos scripts causarán un retraso de entrada que impactará al INP. Para cada plugin, pregúntate: ¿puedo lograr la misma funcionalidad con código a medida o una solución en el servidor?
  • Elige temas ligeros. Muchos temas de WordPress "ofrecen de todo". Aunque parece una gran idea, significa que probablemente están llenos de funcionalidad sin usar que consume valioso tiempo de CPU.
  • Evita los constructores de páginas. Los constructores de páginas como Elementor o WPBakery te dan una interfaz amigable para crear diseños. Por desgracia, suelen depender de scripts pesados para presentar ese diseño a los visitantes.
  • Carga los scripts solo cuando sean necesarios. WordPress tiende a cargar todos los scripts en todas las páginas. Para solucionarlo, crea un tema hijo y anula el registro de los scripts innecesarios por tipo de página:
function my_deregister_scripts() {
  if ( ! is_page( 'contact' ) ) {
    // Anula el registro del script del formulario de contacto en otras páginas
    wp_dequeue_script( 'contact-form-script' );
  }
}
add_action( 'wp_enqueue_scripts', 'my_deregister_scripts' );
  • Audita tu Tag Manager. Los contenedores de Google Tag Manager suelen acumular etiquetas con el tiempo. Cada etiqueta que se dispara durante la carga añade una tarea al main thread. Elimina las etiquetas sin usar y configura disparadores adecuados (por ejemplo, dispara las etiquetas de marketing solo en páginas de conversión). Usa los informes de rendimiento integrados del Tag Manager para identificar etiquetas lentas.
  • Retrasa los scripts de terceros no esenciales. Los widgets de chat, las herramientas de feedback y los incrustados de redes sociales no necesitan cargar inmediatamente. Usa requestIdleCallback() o un disparador basado en scroll para cargarlos solo cuando el usuario vaya a necesitarlos. Para estrategias detalladas, lee nuestra guía sobre 14 métodos para diferir JavaScript.

React / Next.js

Los sitios de React y Next.js están impulsados principalmente por JavaScript. Ejecutar los scripts de inicio, hidratar los componentes y procesar el DOM virtual lleva tiempo. Esto puede causar retraso de entrada para el Interaction to Next Paint (INP). La buena noticia es que tanto React como Next.js proporcionan herramientas para gestionar esto eficazmente.

  • Usa componentes de servidor (React Server Components en el App Router de Next.js). Los componentes de servidor se renderizan en el servidor y envían cero JavaScript al cliente. Esto reduce directamente la cantidad de código que compite por el tiempo del main thread.
  • Carga los scripts de terceros con la estrategia correcta. En Next.js, usa el componente next/script con strategy="afterInteractive" para los scripts necesarios tras la hidratación, o strategy="lazyOnload" para los scripts que pueden cargar durante el tiempo de inactividad del navegador. Consulta nuestra guía sobre async vs defer para JavaScript para conocer los principios subyacentes.
  • Implementa un patrón idle-until-urgent. Este patrón prioriza las interacciones del usuario sobre las tareas de fondo. Usa requestIdleCallback() para la inicialización no crítica, manteniendo un fallback síncrono que se activa cuando el componente se necesita realmente.
  • Usa lazy loading en los componentes. Aplica lazy loading a los componentes que no se necesiten inmediatamente mediante React.lazy() o el dynamic() de Next.js con { ssr: false } para componentes exclusivos del cliente.
  • Usa Suspense para componentes interactivos. Envuelve los componentes interactivos en límites <Suspense>. Así el resto de la página puede renderizarse y volverse interactiva mientras los componentes pesados cargan en segundo plano. Esto evita que un solo componente lento bloquee el procesamiento de entrada en toda la página.
  • Usa transiciones de React para actualizaciones no urgentes. Envuelve las actualizaciones de estado no críticas en startTransition(). De este modo, React puede interrumpirlas si el usuario realiza una nueva interacción. Esto mantiene la UI receptiva incluso durante grandes re-renderizados en curso.

Explora las otras fases del INP

Para controlar tu INP, aborda también las otras dos fases:

  • Tiempo de procesamiento: Optimiza el código del manejador de eventos que se ejecuta durante la interacción. En la mayoría de las páginas, aquí es donde más compensa tu esfuerzo de optimización.
  • Retraso de presentación: Reduce el trabajo de renderizado y pintado que sigue al procesamiento del evento. En páginas complejas con DOMs grandes, esta suele ser la fase más larga.

Para un flujo de trabajo de diagnóstico completo, lee nuestra guía sobre cómo encontrar y solucionar problemas del INP, y vuelve a la página central del INP para ver el panorama completo.

Entérate de qué va lento de verdad.

Trazo tu critical rendering path con datos reales. Te paso una lista de fixes priorizada. No otro informe de Lighthouse.

Quiero la auditoría
Retraso de entrada del INP: causas, diagnóstico y soluciones Core Web Vitals Retraso de entrada del INP: causas, diagnóstico y soluciones