関数のスロットルとデバウンスの違い


250

レート制限を目的とした関数のスロットルとデバウンスの違いについて、誰でも簡単に説明できますか?

私には両方とも同じことをしているようです。私はこれらの2つのブログを調べて確認しました。

http://remysharp.com/2010/07/21/throttling-function-calls

http://benalman.com/projects/jquery-throttle-debounce-plugin/


102
demo.nimius.net/debounce_throttleは優れた視覚化です
thriqon

4
@thriqonその視覚化は私の説明よりも優れています。
ドナル2014

はい、その1つがこの概念の理解にも役立ちました...元の作者の+1 ;-)
thriqon

私が理解するのに役立つ非常に単純な例。jsfiddle.net/Voronar/sxjy25ew/1
Kirill A. Khalitov

回答:


345

簡単に言えば:

  • スロットルは、関数の実行を遅らせます。複数回発生するイベントの通知を減らします。
  • デバウンスは、関数への一連の順次呼び出しをその関数への単一の呼び出しにまとめます。これにより、複数回発生するイベントに対して1つの通知が確実に行われます。

ここで違いを視覚的に確認できます

頻繁に呼び出される関数がある場合-たとえば、サイズ変更またはマウス移動イベントが発生した場合、それは何度も呼び出される可能性があります。この動作を望まない場合は、スロットルして、関数が定期的に呼び出されるようにすることができます。デバウンスとは、一連のイベントの終了時(または開始時)に呼び出されることを意味します。


9
thriqonの視覚化リンクは、それがいかにうまく機能するかを示していると思います。頻繁に呼び出される関数がある場合-たとえば、サイズ変更またはマウス移動イベントが発生した場合、それは何度も呼び出される可能性があります。これが必要ない場合は、スロットルして、関数が定期的に呼び出されるようにすることができます。デバウンスとは、一連の呼び出しの終了時(または開始時)に呼び出されることを意味します。
ドナル

10
@AdamM。ここで視覚化を見てください:demo.nimius.net/debounce_throttle
Donal

2
@AdamM。いいえ。デモでマウスを動かし、時々マウスの動きを止めることで、これを視覚化できます。デバウンス・バーは「カチカチ」になる、スロットル・バーは「カチカチ」続ける一方で、あなたはすべてのマウスの動きを停止している間にマウスが動いている、しかし、減少(スロットル)のレートで。
John Weisz

26
ビジュアライゼーションはすごくいいです。ありがとう!
Sammi

4
リンクは千の言葉よりも価値があります
Finesse '22

148

個人的に、スロットルよりもデバウンスを理解するのは難しいと感じました。

どちらの関数も、実行を延期し、実行率を下げるのに役立ちます。スロットル/デバウンスによって繰り返し返される装飾された関数を呼び出していると仮定します...

  • スロットル:元の関数は、指定された期間ごとに最大1回呼び出されます。
  • デバウンス:元の関数は、指定された期間のに呼び出し元が装飾された関数の呼び出しを停止したに呼び出されます

デバウンスの最後の部分は、達成しようとしている目標を理解するために重要であることがわかりました。_.debounceの実装の古いバージョンも理解に役立ちます(https://davidwalsh.name/function-debounceの好意による)。

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

遠く離れた比喩ですが、おそらく役立つかもしれません。

IMを介してあなたと話すのが好きなChattyという友達がいます。彼女が話すとき、5秒ごとに新しいメッセージを送信し、IMアプリケーションアイコンが上下にバウンドしていると仮定すると、...

  • 素朴なアプローチ:届く限り、すべてのメッセージをチェックします。アプリのアイコンがバウンドしたら、確認します。これは最も効果的な方法ではありませんが、常に最新の状態です。
  • スロットルアプローチ:5分ごとにチェックします(新しいものがある場合)。新しいメッセージが届いたときに、過去5分間にチェックした場合は無視してください。ループにいる間、このアプローチで時間を節約できます。
  • デバウンスアプローチ:Chattyは知っています。彼女はストーリー全体を断片に分解し、メッセージごとに送信します。Chattyがストーリー全体を終了するまで待機します。彼女が5分間メッセージの送信を停止した場合、Chattyは終了したと想定し、すべてをチェックします。

17
これを読むまで、これら2つの関数の違いを理解していませんでした。ありがとう
Seamus Barrett

7
比喩は、私がスロットルとデバウンスについて今まで読んだ中で最も優れた例の1つです。ありがとう。
Vignesh

96

違い

+--------------+-------------------+-------------------+
|              |  Throttle 1 sec   |  Debounce 1 sec   |
+--------------+-------------------+-------------------+
| Delay        | no delay          | 1 sec delay       |
|              |                   |                   |
| Emits new if | last was emitted  | there is no input |
|              | before 1 sec      |  in last 1 sec    |
+--------------+-------------------+-------------------+

ユースケースによる説明

  • 検索バー-ユーザーがキーを押すたびに検索したくないですか?ユーザーが入力を1秒間停止したときに検索したい。debounceキーを押してから1秒を使用します。

  • シューティングゲーム-ピストルは各ショットの間に1秒かかりますが、ユーザーはマウスを複数回クリックします。throttleマウスクリックで使用します。

役割を逆にする

  • 検索バーで1秒スロットル -ユーザーabcdefghijがのすべての文字で入力した場合0.6 sec。次に、スロットルを最初にa押すとトリガーされます。次の1秒間はすべてのプレスをb無視します。つまり、0.6秒では無視されます。その後c、1.2秒で再びトリガーされ、時刻が再びリセットされます。したがってd無視され、eトリガーされます。

  • 1秒間ピストルを跳ね返す-ユーザーが敵を見つけたとき、マウスをクリックしますが、発砲しません。彼はその秒で数回もう一度クリックしますが、それは撃ちません。彼はまだ弾丸が付いているかどうかを確認し、その時点(最後のクリックから1秒後)にピストルが自動的に発砲します。


37

スロットルは、時間の経過とともに関数を呼び出すことができる最大回数を強制します。「この関数は最大で100ミリ秒に1回実行する」のように。

デバウンスは、関数が呼び出されずに一定の時間が経過するまで関数が再度呼び出されないようにします。「この関数が呼び出されずに100ミリ秒が経過した場合にのみこの関数を実行する」のように。

ref


20

スロットル(1秒):こんにちは、私はロボットです。あなたが私にpingを送り続ける限り、私はあなたに話し続けますが、正確にそれぞれ1秒後に。1秒経過する前にpingを送信しても、1秒間隔で返信します。つまり、正確な間隔で返信するのが大好きです。

デバウンス(1秒):こんにちは、私は^^ロボットのいとこです。あなたが私にpingを送信し続ける限り、最後にpingを送信してから 1秒が経過した後にのみ返信するので、私は沈黙します。態度に問題があるのか​​、人を邪魔したくないだけなのかはわかりません。つまり、最後の呼び出しから1秒が経過する前に応答を要求し続けると、応答は得られません。ええええ...どうぞ!失礼と呼んでください。


スロットル(10分):私はロギングマシンです。私は、定期的に10分間隔でシステムログをバックエンドサーバーに送信します。

デバウンス(10秒):こんにちは、私はそのロギングマシンのいとこではありません。(すべてのデバウンサーがこの架空の世界のスロットルに関連しているわけではありません)。私は近くのレストランでウェイターとして働いています。注文にアイテムを追加し続ける限り、注文の執行のためにキッチンに行くことはありません。最後に注文を変更してから10秒が経過した場合にのみ、注文が完了したと見なします。そうして初めて、私はあなたの注文をキッチンで実行します。


クールなデモ:https : //css-tricks.com/debouncing-throttling-explained-examples/

ウェイターの類推のクレジット:https : //codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf


1
最高の説明。
Karan Sharma

17

デバウンスを使用すると、関数が受信できる呼び出しの頻度を管理できます。特定の関数で発生する複数の呼び出しを組み合わせて、特定の期間が満了する前に発生する繰り返し呼び出しが無視されるようにします。基本的にデバウンスは、複数回発生する可能性があるイベントに対して正確に1つの信号が送信されることを保証します。

スロットリングは、関数が受け取る呼び出しの頻度を一定の時間間隔に制限します。これは、ターゲット関数が指定された遅延よりも頻繁に呼び出されないようにするために使用されます。スロットルとは、繰り返し発生するイベントの速度の低下です。


17

それは簡単です。

スロットルが呼び出されている間、ラップされた関数が定期的に実行され、デバウンスは実行されないことを除いて、これらはまったく同じことを行います(レート制限)。デバウンスは、最後に一度だけ関数を(試行して)呼び出します。

:スクロールしている場合、スロットルはスクロール中(Xミリ秒ごと)にゆっくりと関数を呼び出します。デバウンスは、スクロールが完了して関数を呼び出すまで待機します。


これらのデモでは、最後のイベントの後でデバウンスが常にXミリ秒発生するため、「同一」に見えない可能性があることに注意する必要がありますが、スロットルの最後の呼び出しはより早く発生する可能性があります(通常、デバウンスが発生するときに再度呼び出す必要はありません。 )。それはかなり重要ではありませんが、デモを見るかどうか言及する価値があります。
ライアンテイラー

16

素人の言葉で:

デバウンスを使用すると、関数が頻繁に呼び出されているに関数が実行されなくなります。デバウンスされた関数は、呼び出されなくなったと判断されたにのみ実行されます。その時点で、関数は1回だけ実行されます。デバウンスの実用的な例:

  • ユーザーが「タイピングを中止」した場合のテキストフィールドの内容の自動保存または検証:操作は一度だけ行われ、ユーザーがタイピングを停止している(キーを押していない)と判断された後に実行されます。

  • ユーザーがマウスを置いた場所のログ:ユーザーはマウスを動かしていないため、(最後の)位置をログに記録できます。

スロットリングは、呼び出し頻度に関係なく、最近実行された関数が実行されるのを防ぎます。スロットルの実用的な例:

  • v-syncの実装はスロットルに基づいています。画面は、最後の画面描画から16ミリ秒が経過した場合にのみ描画されます。画面更新機能が何度呼び出されても、最大で16ミリ秒に1回しか実行されません。

7

個人的に覚えておくのに役立つ実際の例え:

  • debounce =会話。返信する前に、相手が話し終わるのを待ちます。
  • スロットル=ドラムビット。単純な4/4ドラムビットでのみノートを演奏します。

デバウンスの使用例:

  • タイピング。ユーザーが入力をやめた後で何かしたい。したがって、最後のキーストロークから1秒待つのは理にかなっています。キーを押すたびに待機が再開されます。
  • アニメーション。ユーザーが要素の上にマウスを置くのをやめた後、要素を縮小して戻したいとします。デバウンスを使用しないと、「ホット」ゾーンと「コールド」ゾーンの間でカーソルが意図せず移動して、アニメーションが不安定になる可能性があります。

スロットルの使用例:

  • スクロール。スクロールに反応したいが、計算の量を制限したいので、100msごとに何かを行うだけで、潜在的な遅延を防ぐことができます。
  • マウスの動き。スクロールと同じですが、マウスを移動します。
  • API呼び出し特定のUIイベントでAPI呼び出しを発生させたいが、サーバーに過負荷をかけないようにするAPI呼び出しの数を制限したい。

4

throtleは単なるラッパーであるデバウンスなりデバウンスが渡されたコールするfunction場合は、ある程度の期間でデバウンスは、その後に指定された大きいの期間の関数呼び出し遅延throtleを



2

スロットル

スロットルは、関数を時間外に呼び出すことができる最大回数を強制します。「この関数は最大で100ミリ秒に1回実行する」のように。通常の状況では、この関数を10秒間に1,000回呼び出すとします。100ミリ秒に1回だけスロットルすると、その関数は最大で100回しか実行されません。

(10s * 1,000) = 10,000ms
10,000ms / 100ms throttling = 100 maximum calls

デバウンス

デバウンスは、関数が呼び出されずに一定の時間が経過するまで関数が再度呼び出されないようにします。「この関数が呼び出されずに100ミリ秒が経過した場合にのみこの関数を実行する」のように。

おそらく、関数は3秒間に分散されたクイックバーストで1,000回呼び出され、その後呼び出されなくなります。100ミリ秒でデバウンスした場合、バーストが終了すると、関数は3.1秒に1回だけ実行されます。バースト中に関数が呼び出されるたびに、デバウンスタイマーがリセットされます

ソース:- スロットルとデバウンス


2

イベント「E」で呼び出されるコールバック関数「cb」があるとします。「E」が1秒間に1000回トリガーされるとすると、「cb」への呼び出しは1000回になります。つまり、1コール/ミリ秒です。最適化するには、次のいずれかを使用できます。

  • スロットリング:(100ミリ秒)の絞りで、 "CBは、" [第百ミリ秒、200番目ミリ、300番目のMS、...第千ミリ秒]で呼び出されます。つまり、1コール/ 100 msです。ここでは、「cb」への1000コールが10コールに最適化されています。
  • デバウンス:(100ms)のデバウンスでは、「cb」は[1100秒]に1回だけ呼び出されます。それは、[1000th ms]に発生した「E」の最後のトリガーから100msです。ここでは、1回の呼び出しに最適化された「cb」への1000回の呼び出し。

1

私が理解している限り、簡単に言えば、スロットリング-特定の回数だけsetInterval(callback)を呼び出すのと同じです。または、イベントの発生から一定の時間が経過した後に関数を呼び出す。このリンクは役に立ちます -https : //css-tricks.com/the-difference-between-throttling-and-debouncing/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.