Cómo optimizar el retraso de entrada

Descubre qué es la demora en la entrada y aprende técnicas para reducirla y lograr una interactividad más rápida.

Las interacciones en la web son cosas complicadas, con todo tipo de actividad en el navegador para guiarlas. No obstante, lo que todos tienen en común es que incurren en un retraso de entrada antes de que sus devoluciones de llamada de eventos comiencen a ejecutarse. En esta guía, aprenderás qué es la demora en la entrada y qué puedes hacer para minimizarla y que las interacciones de tu sitio web se ejecuten más rápido.

¿Qué es la demora en la entrada?

El retraso de entrada es el período que comienza desde la primera vez que el usuario interactúa con una página (como presionar una pantalla, hacer clic con el mouse o presionar una tecla) hasta que comienzan a ejecutarse las devoluciones de llamada del evento para la interacción. Cada interacción comienza con un retraso de entrada determinado.

Visualización simplificada del retraso de entrada A la izquierda, aparece el arte lineal de un cursor de mouse con un pico de estrellas detrás, que indica el inicio de una interacción. A la derecha, aparece el diseño de línea de un engranaje, que indica cuándo comienzan a ejecutarse los controladores de eventos para una interacción. El espacio intermedio se indica con una llave como el retraso de entrada.
La mecánica detrás del retraso de entrada. Cuando el sistema operativo recibe una entrada, esta debe pasarse al navegador antes de que comience la interacción. Esto tarda una cierta cantidad de tiempo y puede aumentarse según el trabajo del subproceso principal existente.

Parte de la demora de entrada es inevitable: el sistema operativo siempre tarda un tiempo en reconocer un evento de entrada y transmitirlo al navegador. Sin embargo, esa parte del retraso de entrada a menudo ni siquiera se percibe, y hay otras cosas en la página que pueden hacer que las demoras de entrada sean lo suficientemente largas como para causar problemas.

Cómo pensar en la demora en la entrada

En términos generales, tu objetivo es que cada parte de una interacción sea lo más breve posible para que tu sitio web tenga más probabilidades de alcanzar el umbral de buena calidad de la métrica Interacción hasta la siguiente pintura (INP), independientemente del dispositivo del usuario. Controlar la demora en las entradas es solo una parte de alcanzar ese umbral.

Por lo tanto, te recomendamos que intentes hacer el menor retraso de entrada posible para alcanzar el umbral “bueno” de INP. Sin embargo, debes tener en cuenta que no puedes eliminar las demoras de entrada por completo. Siempre y cuando evites realizar un trabajo excesivo en el subproceso principal mientras los usuarios intentan interactuar con tu página, la demora de entrada debe ser lo suficientemente baja como para evitar problemas.

Cómo minimizar la demora en la entrada

Como se mencionó anteriormente, es inevitable cierto retraso de entrada, pero, por otro lado, se puede evitar cierta demora de entrada. A continuación, se incluyen algunos aspectos que debes tener en cuenta si tienes problemas con retrasos largos en las entradas.

Evita los temporizadores recurrentes que inicien un trabajo excesivo en el subproceso principal

Existen dos funciones de temporizador de uso general en JavaScript que pueden contribuir al retraso de la entrada: setTimeout y setInterval. La diferencia entre ambos es que setTimeout programa una devolución de llamada para que se ejecute después de un tiempo especificado. setInterval, por otro lado, programa una devolución de llamada para que se ejecute cada n milisegundos de forma permanente o hasta que el temporizador finalice con clearInterval.

setTimeout no es un problema en sí; de hecho, puede ser útil para evitar tareas largas. Sin embargo, depende de cuándo se produce el tiempo de espera y de si el usuario intenta interactuar con la página cuando se ejecuta la devolución de llamada de tiempo de espera.

Además, setTimeout se puede ejecutar en un bucle o de manera recursiva, en el que actúa de manera más parecida a setInterval, aunque es preferible que no se programe la próxima iteración hasta que se complete la anterior. Si bien esto significa que el bucle cederá al subproceso principal cada vez que se llame a setTimeout, debes asegurarte de que su devolución de llamada no haga un trabajo excesivo.

setInterval ejecuta una devolución de llamada en un intervalo y, por lo tanto, es mucho más probable que interfiera en las interacciones. Esto se debe a que, a diferencia de una sola instancia de una llamada a setTimeout, que es una devolución de llamada única que puede obstaculizar la interacción del usuario, la naturaleza recurrente de setInterval hace que sea mucho más probable que interrumpe una interacción, por lo que aumenta el retraso de entrada de la interacción.

Captura de pantalla del generador de perfiles de rendimiento en las Herramientas para desarrolladores de Chrome que muestra el retraso de entrada Una tarea activada por una función de temporizador ocurre justo antes de que un usuario inicie una interacción de clic. Sin embargo, el temporizador extiende el retraso de entrada, lo que hace que las devoluciones de llamada de los eventos de la interacción se ejecuten más tarde.
Un temporizador registrado por una llamada setInterval anterior que contribuye a la demora de entrada, como se muestra en el panel de rendimiento de las Herramientas para desarrolladores de Chrome. El retraso de entrada agregada hace que las devoluciones de llamada del evento para la interacción se ejecuten más tarde de lo que podrían.

Si se producen temporizadores en el código propio, tú tienes el control sobre ellos. Evalúa si los necesitas o si haces todo lo posible para reducirlo tanto como sea posible. Sin embargo, los tiempos de exposición en los guiones de terceros son una historia diferente. A menudo, no tienes control sobre lo que hace una secuencia de comandos de terceros y corregir los problemas de rendimiento en el código de terceros suele implicar trabajar con las partes interesadas para determinar si una secuencia de comandos de terceros determinada es necesaria y, de ser así, establecer contacto con un proveedor de secuencias de comandos de terceros para determinar qué se puede hacer para solucionar los problemas de rendimiento que pueden causar en tu sitio web.

Evita tareas largas

Una forma de mitigar las demoras de entrada largas es evitar tareas largas. Cuando tienes exceso de trabajo en el subproceso principal que bloquea este durante las interacciones, se sumará al retraso de entrada correspondiente antes de que las tareas largas hayan tenido la oportunidad de finalizar.

Visualización de cuánto tiempo extienden el retraso de entrada de las tareas. En la parte superior, una interacción ocurre poco después de que se ejecuta una sola tarea larga, lo que provoca un retraso de entrada significativo que hace que las devoluciones de llamada de eventos se ejecuten mucho más tarde de lo que deberían. En la parte inferior, una interacción ocurre aproximadamente al mismo tiempo, pero la tarea larga se divide en varias más pequeñas mediante la generación, lo que permite que las devoluciones de llamada del evento de la interacción se ejecuten mucho antes.
Una visualización de lo que sucede con las interacciones cuando las tareas son demasiado largas y el navegador no puede responder con la rapidez suficiente a las interacciones, en comparación con cuando las tareas más largas se dividen en tareas más pequeñas.

Además de minimizar la cantidad de trabajo que realizas en una tarea (y siempre debes esforzarte por hacer el menor trabajo posible en el subproceso principal), puedes mejorar la capacidad de respuesta a las entradas del usuario dividiendo las tareas largas.

Ten en cuenta la superposición de interacciones

Una parte particularmente desafiante de la optimización de INP puede ser si hay interacciones que se superponen. La superposición de interacciones implica que, después de interactuar con un elemento, se realiza otra interacción con la página antes de que la interacción inicial haya tenido la oportunidad de renderizar el siguiente fotograma.

Representación del momento en que las tareas pueden superponerse para producir grandes retrasos en las entradas. En esta representación, una interacción de clic se superpone con una interacción de keydown para aumentar la demora de entrada para la interacción de keydown.
Se muestra una visualización de dos interacciones simultáneas en el generador de perfiles de rendimiento de las Herramientas para desarrolladores de Chrome. El trabajo de renderización en la interacción de clic inicial provoca una demora en la entrada de la siguiente interacción del teclado.

Las fuentes de superposición de interacciones pueden ser tan simples como cuando los usuarios realizan muchas interacciones en un corto período de tiempo. Esto puede ocurrir cuando los usuarios escriben en campos de formulario, donde pueden ocurrir muchas interacciones con el teclado en un período muy corto. Si el trabajo en un evento clave es particularmente costoso, como en el caso común de campos de autocompletado en el que las solicitudes de red se realizan a un backend, tienes algunas opciones:

  • Considera revocar las entradas para limitar la cantidad de veces que se ejecuta una devolución de llamada de evento en un período determinado.
  • Usa AbortController para cancelar las solicitudes fetch salientes, de modo que el subproceso principal no se congestione y controle las devoluciones de llamada fetch. Nota: La propiedad signal de una instancia de AbortController también se puede usar para anular eventos.

Otra fuente de mayor demora de entrada debido a interacciones superpuestas pueden ser las animaciones costosas. En particular, las animaciones en JavaScript pueden activar muchas llamadas requestAnimationFrame, que podrían impedir las interacciones del usuario. Para solucionar este problema, usa animaciones de CSS siempre que sea posible, a fin de evitar poner en cola fotogramas de animación que puedan ser costosos. Sin embargo, si lo haces, asegúrate de evitar las animaciones no compuestas para que las animaciones se ejecuten principalmente en la GPU y los subprocesos del compositor, y no en el subproceso principal.

Conclusión

Si bien es posible que los retrasos en las entradas no representen la mayor parte del tiempo que tardan en ejecutarse tus interacciones, es importante comprender que cada parte de una interacción ocupa una cantidad de tiempo que puedes reducir. Si observas un retraso de entrada prolongado, tienes oportunidades de reducirlo. Evitar devoluciones de llamadas recurrentes de temporizadores, dividir tareas largas y estar al tanto de la posible superposición de interacciones puede ayudarte a reducir la demora en las entradas, lo que genera una interactividad más rápida para los usuarios de tu sitio web.

Hero image de Unsplash, de Erik Mclean.