Der Unterschied zwischen Throttling und Debouncing

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ich habe diese Begriffe neulich verwechselt und jemand hat mich korrigiert. Also habe ich es auf meine Liste von Blog-Ideen gesetzt und hier sind wir. Beides sind Wege, um die Menge an JavaScript zu begrenzen, die wir aufgrund von DOM-Ereignissen aus Performance-Gründen ausführen. Aber sie sind, Sie haben es erraten, unterschiedlich.

Throttling erzwingt eine maximale Anzahl von Aufrufen einer Funktion über die Zeit. Wie in „Diese Funktion höchstens einmal alle 100 Millisekunden ausführen.“

Angenommen, unter normalen Umständen würden Sie diese Funktion 1.000 Mal über 10 Sekunden aufrufen. Wenn Sie sie auf nur einmal pro 100 Millisekunden drosseln, wird diese Funktion höchstens 100 Mal ausgeführt.

(10s * 1.000) = 10.000 ms
10.000 ms / 100 ms Throttling = 100 maximale Aufrufe

Debouncing erzwingt, dass eine Funktion nicht erneut aufgerufen wird, bis eine bestimmte Zeit vergangen ist, ohne dass sie aufgerufen wurde. Wie in „Diese Funktion nur ausführen, wenn 100 Millisekunden vergangen sind, ohne dass sie aufgerufen wurde.“

Vielleicht wird eine Funktion 1.000 Mal in einem schnellen Burst aufgerufen, verteilt über 3 Sekunden, und dann nicht mehr. Wenn Sie sie mit 100 Millisekunden debounce, wird die Funktion nur einmal, nach 3,1 Sekunden, einmal nach dem Burst feuern. Jedes Mal, wenn die Funktion während des Bursts aufgerufen wird, wird der Debouncing-Timer zurückgesetzt.

Was ist der Sinn?

Ein wichtiger Anwendungsfall für diese Konzepte sind bestimmte DOM-Ereignisse wie Scrollen und Größenänderung. Wenn Sie beispielsweise einen Scroll-Handler an ein Element anhängen und dieses Element um beispielsweise 5000 Pixel nach unten scrollen, werden wahrscheinlich mehr als 100 Ereignisse ausgelöst. Wenn Ihr Ereignis-Handler eine Menge Arbeit leistet (wie z. B. schwere Berechnungen und andere DOM-Manipulationen), kann es zu Leistungsproblemen (Ruckeln) kommen. Wenn Sie den Handler weniger oft ausführen können, ohne die Benutzererfahrung wesentlich zu beeinträchtigen, ist es wahrscheinlich sinnvoll.

Kurze Beispiele

  • Warten Sie, bis der Benutzer die Fenstergröße ändert
  • Lösen Sie kein Ajax-Ereignis aus, bis der Benutzer mit dem Tippen aufhört
  • Messen Sie die Scroll-Position der Seite und reagieren Sie höchstens alle 50 ms
  • Sorgen Sie für gute Leistung, während Sie Elemente in einer App ziehen

Wie macht man das?

Funktionen für beides sind in Underscore und Lodash integriert. Selbst wenn Sie diese Bibliotheken nicht vollständig verwenden, könnten Sie die Funktionen daraus extrahieren und für Ihren eigenen Gebrauch verwenden.

Einfaches gedrosseltes Scrollen

$("body").on('scroll', _.throttle(function() {
  // Do expensive things
}, 100));

Einfaches debounced Größenänderung

$(window).on('resize', _.debounce(function() {
  // Do expensive things
}, 100));

Um dies zu verbessern, würden Sie die Verwendung von requestAnimationFrame einbeziehen, so dass der Browser die Ausführung der Funktionen zu seinem eigenen optimalen Zeitpunkt durchführt. Dies wird in diesem Tutorial von Paul Lewis behandelt.

Demo

Einfache Demo, damit Sie den Unterschied erleben können

Sehen Sie den Pen Der Unterschied zwischen Throttling, Debouncing und Keinem von Chris Coyier (@chriscoyier) auf CodePen.


Update: Mehr Demos!