debounce と throttle

(関数)
https://www.webdesignleaves.com/pr/jquery/debounce-and-throttle.html

リサイズやスクロールイベントなど高い頻度で発生するイベントで、イベントが発生する度にコールバック関数を呼び出して実行するとブラウザに負担がかかったり、UX 上好ましくない場合がある。
Debounce や Throttle は、一定期間に(コールバック)関数が呼び出される回数を制限するための手法で、不必要な関数の実行を制御することができる。
例えば、ユーザーが操作を終了するのを待ってからコールバック関数を呼び出せばよい場合は、Debounce を利用してイベントが一定期間発生しない場合に関数を呼び出すことができる。
Throttle を利用すると、コールバック関数の呼び出しを一定の割合で間引く(呼び出し回数を減らす)ことができる。

debounce

const debouncedFunc = debounce(func, timeout);

Debounce は対象の関数が呼び出されてから次に呼び出されるまでに一定の時間が経過したら実行し、指定された時間内に再度呼び出された場合は待機させる。言い換えると、連続して繰り返される処理が指定した時間内に発生した場合に、最後(または最初)の1回だけ実行するようにする。
関数 debounce() は呼び出しを制御したい関数(func)と待機時間(timeout)を引数に受け取り、受け取った関数を指定された時間待機させるように拡張したラッパー関数を返すデコレータ関数である。
(※関数を引数に受け取って、その関数を拡張して返す関数をデコレータ関数と呼ぶ)

debounceのメリットは以下の通り。

  • パフォーマンスの向上:不要な関数の実行を抑制することで、アプリケーションのパフォーマンスを向上させることができる。
  • APIのコスト削減:ユーザーの入力ごとにAPIを呼び出すのを防ぐことで、APIのリクエスト回数を減少させることができる。
  • ユーザーエクスペリエンスの向上:イベントの高頻度発火による不要な動作やアニメーションを避けることで、よりスムーズなユーザーエクスペリエンスを提供できる。

例)ウィンドウのリサイズイベント
以下の例は、ウィンドウのリサイズイベントが高頻度で発火するのを防いでいる。
この実装により、ウィンドウがリサイズされたときに300ミリ秒間何も発火しなかった場合のみ、console.log(‘Debounced!’);が実行される。

const debouncedFunction = debounce(() => {
    console.log('Debounced!');
}, 300);
window.addEventListener('resize', debouncedFunction);

例)入力フォームとAPIリクエスト
ユーザーがテキスト入力をするたびにAPIリクエストを送るのを防ぐ。

const debouncedSearch = debounce((query) => {
    fetch(`https://api.example.com/search?q=${query}`)
        .then(response => response.json())
        .then(data => {
            // 結果の表示や処理
        });
}, 500);
document.querySelector('#search-input').addEventListener('input', (e) => {
    debouncedSearch(e.target.value);
});

throttle

const throttledFunc = throttle(func, timeout);

Throttle は Debounce とは異なり、ほぼ一定の間隔で処理を実行する場合に利用することができる。
Throttle は呼び出された関数の実行を一定時間あたり一回に間引くテクニックで、関数が一定時間ごとに複数回呼び出されるのを防ぎ、関数が(ほぼ)固定レートで定期的に実行されるようにする。
この関数は引数に対象の関数と待機時間(func, timeout)を受け取り、受け取った関数を一定間隔で実行する機能を追加したラッパー関数を返すデコレータ関数である。

// throttle() を利用してリサイズイベントで 300ms に一回ウィンドウ幅をコンソールに出力する
window.addEventListener('resize', throttle( (e) => {
  console.log(e.target.innerWidth);
}, 300));
inserted by FC2 system