Segui su:
Programmazione Web Italia

Throttle e debounce in javascript: cosa sono e come usarli (con esempi)

Throttle e debounce in javascript: cosa sono e come usarli (con esempi)

Quando il nostro codice deve rimanere in ascolto di eventi che vengono generati troppo frequentemente, è possibile un notevole calo delle prestazioni e conseguente deterioramento dell'esperienza utente. Uno sviluppatore deve saper agire di conseguenza togliendo dal suo cappello virtuale due degli strumenti più utili in questi casi: il debouncing e il throttling!Marco dice...

Introduzione

Nella programmazione JavaScript, capita spesso di dover gestire eventi che accadono o si susseguono ad intervalli di tempo molto frequenti; per esempio lo scoll del mouse, il resize della finestra o la digitazione di alcuni caratteri all'interno di un campo di testo. Nel primo caso in elenco, lo scroll della rotellina del mouse per visualizzare il contenuto below-the-fold può generare decine se non centinaia (dipende dalla velocità di scoll) di eventi. Se il nostro compito, come programmatori, è quello di mettersi all'ascolto di questi eventi e lanciare l'esecuzione di un metodo ad ognuno di essi, potremmo incorrere in seri problemi di performance con rallentamenti visibili nelle applicazioni e conseguente degradazione della user experience.

Qui entrano in gioco due tecniche fondamentali: throttle e debounce. Entrambe servono a limitare il numero di volte in cui una funzione viene eseguita, ma lo fanno in modi diversi e con scopi differenti. In questo articolo vedremo ciascuna di queste tecniche, quando usarle e come implementarle.

Cos'è il debounce in JavaScript?

Il debounce è una tecnica di programmazione che assicura che una funzione venga eseguita solo dopo un determinato intervallo di tempo dall'ultima volta in cui è stata chiamata. Lo scopo è quella di evitare esecuzioni continue di una certa funzione per evitare problemi di performance, ma senza intaccare la funzionlità della applicazione.

Immaginiamo un campo di ricerca che effettua richieste al server man mano che l'utente digita. In questo caso, ogni tasto premuto genera un evento che potrebbe inviare una richiesta. Il debounce evita che vengano effettuate troppe richieste ravvicinate, eseguendo la funzione solo dopo che l'utente ha smesso di digitare per un certo periodo di tempo.

Utilizzo del debounce per limitare le chiamate al server

function debounce(func, delay) {
  let timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, args), delay);
  };
}
 
// Uso del debounce
const handleSearch = debounce((query) => {
  console.log(`Ricerca per: ${query}`);
}, 300);
 
 
document.getElementById('searchInput').addEventListener('input', (event) => {
  handleSearch(event.target.value);
});
 

Quando usare il debounce

Il debounce è particolarmente utile nei casi in cui desideri eseguire una funzione solo una volta, dopo che una serie di eventi si è conclusa.

  • Campi di ricerca dinamica: evita di inviare una richiesta al server per ogni singola lettera digitata dall'utente. Con il debounce, la ricerca viene eseguita solo quando l'utente ha smesso di digitare per un intervallo di tempo prestabilito.
  • Salvataggi automatici: ideale per applicazioni che salvano automaticamente il contenuto (ad esempio un editor di testo online) solo dopo che l'utente ha terminato di scrivere.
  • Ridimensionamento della finestra: quando vuoi ricalcolare elementi della UI (come griglie o layout) solo dopo che l'utente ha finito di ridimensionare la finestra del browser, evitando di farlo durante ogni singolo pixel di movimento.
  • Validazione dei moduli: riduce il numero di controlli effettuati durante la compilazione di un modulo, eseguendoli solo una volta terminata l'interazione.

Cos'è il throttle in JavaScript?

Il throttle limita il numero di volte in cui una funzione può essere eseguita in un determinato intervallo di tempo. A differenza del debounce, il throttle garantisce che la funzione venga eseguita a intervalli regolari, indipendentemente da quanto frequentemente l'evento viene attivato.

Un esempio comune è il caso dello scroll. Supponiamo di voler calcolare la posizione di un elemento mentre l'utente scorre la pagina. Il throttle limita la frequenza con cui questa funzione viene chiamata, migliorando le performance.

Utilizzo del throttle per limitare le chiamate al server

function throttle(func, limit) {
  let lastFunc;
  let lastRan;
  return function(...args) {
    const context = this;
    if (!lastRan) {
      func.apply(context, args);
      lastRan = Date.now();
    } else {
      clearTimeout(lastFunc);
      lastFunc = setTimeout(() => {
        if ((Date.now() - lastRan) >= limit) {
          func.apply(context, args);
          lastRan = Date.now();
        }
      }, limit - (Date.now() - lastRan));
    }
  };
}
 
// Uso del throttle
const handleScroll = throttle(() => {
  console.log('Evento di scroll!');
}, 200);
 
document.addEventListener('scroll', handleScroll);

Quando usare il throttle

Il throttle è ideale in situazioni in cui desideri garantire un’esecuzione regolare di una funzione durante l’attivazione continua di un evento.

  • Scroll della pagina: se vuoi monitorare la posizione di scroll per attivare effetti grafici o caricare contenuti dinamici, il throttle consente di aggiornare la UI a intervalli regolari senza sovraccaricare le risorse del browser.
  • Trascinamento degli oggetti (drag-and-drop): durante il drag, puoi aggiornare la posizione dell'oggetto a intervalli regolari per mantenere una transizione fluida senza un eccessivo consumo di CPU.
  • Monitoraggio della finestra (resize): quando l'utente ridimensiona la finestra, il throttle aiuta a limitare il numero di ricalcoli dei layout, evitando operazioni ridondanti.
  • Eventi di mousemove: se hai funzioni legate al movimento del mouse (come il tracciamento di un cursore personalizzato o effetti hover complessi), il throttle garantisce performance stabili.
  • Interazioni touch su dispositivi mobili: per gestire swipe o scroll su schermi touch, il throttle riduce il carico computazionale mantenendo un'esperienza fluida.

Differenze tra throttle e debounce

DebounceThrottle
La funzione viene eseguita solo dopo che l'evento si è fermato per un certo periodo di tempo.La funzione viene eseguita a intervalli regolari mentre l'evento si verifica.
Ideale per eventi legati alla digitazione o al resize della finestra.Ideale per eventi frequenti come lo scroll o il mouse move.
Può ritardare l'esecuzione della funzione fino alla fine degli eventi.Garantisce che la funzione venga eseguita regolarmente nel tempo.

Conclusione

Throttle e debounce sono strumenti potenti per migliorare le performance delle applicazioni web. Saperli distinguere e utilizzare correttamente è essenziale per qualsiasi sviluppatore JavaScript. Inizia a sperimentare con i codici proposti e integra queste tecniche nei tuoi progetti per vedere subito i vantaggi!