Unlimited WordPress themes, plugins, graphics & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Web Design
  2. JavaScript

Cómo implementar Debounce y Throttle con JavaScript

Read Time: 7 mins

Spanish (Español) translation by Ana Paulina Figueroa (you can also view the original English article)

En JavaScript, siempre que adjuntamos una función de alto rendimiento a un detector de eventos, se considera una práctica recomendada para controlar la frecuencia con la que se llama a la función. En este tutorial, veremos como implementar funciones anti-rebote y aceleración para regular eventos. 

Todo es cuestión de rendimiento. 

El rendimiento es una preocupación importante al crear páginas web, especialmente para sitios que realizan animaciones e interacciones. Los detectores de eventos son una opción común para implementar interacciones con JavaScript, ya que se utilizan para detectar cambios en una página y llamar a funciones de acuerdo con esos cambios.  Es importante asegurarse de que los scripts de eventos de escucha estén optimizados para el rendimiento. 

¿Cómo impactan los oyentes de eventos en el rendimiento?

Veamos con qué frecuencia se llama a los oyentes de eventos según las acciones del usuario. Realice los eventos correspondientes en la siguiente demostración para ver el recuento: 

Los oyentes de eventos impactan en el rendimiento según los eventos a los que están llamando. 

Supongamos que tenemos una función que es responsable de agregar nuevos elementos al DOM y llamamos a esta función cada vez que el usuario se desplaza. Como hemos visto en la demostración, se puede llamar al detector de eventos de desplazamiento por cada píxel que el usuario se desplaza por la pantalla. 

Agregar elementos al DOM provoca reajustes, que es la forma en el que el navegador calcula la ubicación de nuevos elementos.  Los reflujos se realizan en cascada, por lo que cambiar el reflujo de un elemento provocará un cambio en todos los elementos posteriores y una parte o la totalidad del documento se volverá a representar.  Estos cálculos pueden afectar la velocidad del usuario y ralentizar su página. Puede leer más sobre cómo los reflujos y repintados afectan el rendimiento en este artículo.

Siempre que adjuntamos una función de alto rendimiento a un detector de eventos, se considera una buena práctica controlar la frecuencia con la que se llama a la función. 

Rebote y Acelerador son dos métodos para optimizar el rendimiento de los scripts controlando la frecuencia con la que se llama a un evento. 

Rebote vs. Acelerador

La principal diferencia entre rebote y acelerador es que el rebote llama a una función cuando un usuario no ha llevado acabo un evento en un periodo de tiempo específico, mientras que el acelerador llama a una función a intervalos de un período de tiempo específico mientras el usuario está realizando el evento. 

Por ejemplo, si eliminamos el rebote de una función de desplazamiento con un temporizador de 250ms (milisegundos), la función solo se llama si el usuario no se ha desplazado en 250ms. Si aceleramos una función de desplazamiento con un temporizador de 250ms, la función se llama cada 250ms mientras el usuario se desplaza.  

Esta demostración proporciona una demostración visual del ejemplo anterior: 

Función de rebote con JavaScript Vainilla

Vamos a ampliar más sobre cómo funciona el concepto de rebotes: 

Podemos pensar en ello como una función de espera y ver. Cuando eliminamos el rebote de una función, esperamos a ver si el usuario realiza una acción en un período de tiempo específico y si no, ejecutamos la función. Ahora convierta eso en lógica.

  1. Inicializar una variable de temporizador que controla cuándo ejecutar una función de devolución de llamada. 
  2. Restablece la función del temporizador cada vez que el usuario inicia una acción. 

Así es como se ve la implementación lógica: 

En este código, inicializamos una variable de temporizador llamada Temporizador rebote que controla un método setTimeout. Este método setTimeout es el responsable de llamar a la función de devolución de llamada después del tiempo del parámetro especificado. 

Dentro de nuestra función rebote, primero borramos la función Temporizador rebote cada vez que se llama a la función rebote. Esto es lo que garantiza que no se llame a la función de devolución de llamada hasta que se haya agotado el tiempo.  Si establecemos nuestra función de rebote dentro de un oyente de eventos de desplazamiento, debounceTimer se restablece mediante window.clearTimeout cada vez que el usuario se desplace.

Casos de uso para el rebote

El rebote es un buen método para controlar eventos que requieren acciones esporádicas del usuario, como escribir en un campo de entrada o hacer clic en un botón. En el caso de una barra de búsqueda que realice llamadas API de acuerdo a la entrada del usuario, la implementación del rebote es una buena forma de reducir la cantidad de llamadas realizadas a la API.

En esta demostración, hemos rebotado la entrada del usuario para que solamente devuelva el valor de entrada si el usuario no ha escrito algún texto en 500ms:

Podemos escribir el código de la demostración anterior de esta manera:

Implementación de una función de aceleración con JavaScript puro

Podemos pensar en la aceleración como una función de minimización; esta minimiza el número de llamadas realizadas dentro de un cierto intervalo de tiempo.

Al definir la lógica de la aceleración, tenemos lo siguiente:

  1. Inicializa una variable para detectar si la función ha sido llamada dentro del tiempo especificado.
  2. SI la función ha sido llamada, pausa la función de aceleración.
  3. Si la función no ha sido llamada, o si ha terminado de ejecutarse dentro del intervalo de tiempo, vuelve a ejecutar la función de aceleración.

Podemos escribirlo en JavaScript de esta forma:

A continuación se muestra un desglose de lo que está sucediendo:

  1. La variable throttlePause inicialmente no está definida, por lo que la función pasa a la siguiente línea.
  2. Establecemos el valor de throttlePause en true para la siguiente iteración. Si la función de aceleración es llamada de nuevo antes de que setTimer termine, la función devuelve un valor indefinido.
  3. setTimeout arranca un temporizador para ejecutar la función. El temporizador se ejecuta de forma asíncrona mientras se llama a la función de aceleración, por lo que no se verá afectado por la función de aceleración si esta última es llamada nuevamente.
  4. Una vez que la devolución de llamada haya sido ejecutada, esta establece el valor de throttlePause en false para que la función de aceleración pueda repetirse.

Casos de uso para la aceleración

La aceleración es útil para casos en los que el usuario está llevando a cabo un evento fluido o continuo, como al desplazarse o al cambiar un tamaño. En el caso de la animación de elementos en base a sus posiciones de desplazamiento, o al gestionar una página de desplazamiento infinito, podemos usar la aceleración para controlar la frecuencia con la que se llama al manejador del desplazamiento.

En esta demostración hemos establecido una función de aceleración en un oyente de eventos de desplazamiento:

El código de la demostración anterior se ve así:

Conclusión

Ahora deberías contar con una mejor comprensión de los conceptos y diferencias entre el rebote y la aceleración. También exploramos los enfoques lógicos y la implementación de código de ambos métodos, para que puedas aplicarlos a situaciones de la vida real a fin de optimizar el rendimiento de tus scripts.

Más información sobre JavaScript de front-end

Desde conceptos para principiantes hasta proyectos prácticos, tenemos lo que necesitas:

Advertisement
Did you find this post useful?
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.