LASSIC Media らしくメディア

2026.07.31 らしくコラム

デバウンスとスロットルの違い|過剰処理を抑える

「検索ボックスに文字を打つたびに、検索APIへの問い合わせが飛んでいる」「スクロールするだけで重い処理が走り、画面の動きが引っかかる」。Webアプリケーションの発注やレビューの場面では、こうした過剰な処理呼び出しに関する相談をよく耳にします。イベントが起きるたびに処理を律儀に実行する作りは、通信量や描画負荷を無駄に増やし、体感速度の悪化を招きやすいものです。

この記事では、こうした無駄な呼び出しを間引く代表的な手法である「デバウンス」と「スロットル」を、発注担当者やプロジェクトマネージャー向けに整理します。実装そのものをどう書くかよりも、どの画面にどちらを当てはめ、何を確認すればよいかという判断材料に重きを置きます。レートリミットやバックプレッシャーはサーバー側で受信リクエストの流量を制御する仕組みで、本記事が扱うクライアント側でのイベント間引きとは別の層の対策です。両者の役割を混同しないよう、まずは対象範囲をはっきりさせておきましょう。

蛇口から一定の間隔で落ちる水滴のイメージ。過剰な呼び出しを間引くデバウンス・スロットルの比喩

この記事のポイント

  • デバウンスとスロットルは、短時間に連続するイベントの呼び出しを間引く2つの制御手法です。
  • デバウンスは呼び出しが落ち着くのを待って最後の1回を実行し、スロットルは一定間隔ごとに実行します。
  • サーバー側のレートリミット・バックプレッシャーとは異なる、クライアント側のイベント制御である点も押さえておきたいところです。

デバウンスとスロットルとは

デバウンスとスロットルとは、短時間に何度も発生する処理の呼び出しを間引いて、過剰な実行を抑えるための2つの制御手法です。どちらも、入力・スクロール・マウス移動・ボタン連打といった、ブラウザ上で連続して発生しやすいイベントを対象にします。実装の場所も呼び出し先も同じイベントでありながら、間引き方の性質が異なる点が特徴です。

たとえば検索フォームのオートコンプリートでは、1文字入力するたびに検索APIを呼び出す作りにしたとします。すると確定前の文字列でリクエストが連発し、通信量とサーバー負荷が膨らんでしまうのです。無限スクロールやリサイズに合わせて描画処理をそのつど実行する作りも同様で、イベントの発生頻度に処理が追いつかず、画面の動きが重くなる原因になりやすいといえます。

似た文脈で語られるレートリミットやバックプレッシャーは、主にサーバー側で受信リクエストの流量を制御する仕組みです。本記事で扱うデバウンス・スロットルは、フロントエンドやクライアント側でイベントの発生源そのものを間引く手法であり、扱う層が異なります。

呼び出しを間引かずに放置すると、利用者が増えるほど無駄な通信が積み重なり、サーバー費用や応答速度に響いてきます。反対に間引きすぎると、操作への反応が鈍くなり、使い勝手を損ねてしまうのです。ちょうどよい間引き方を選ぶために、まずは2つの手法の違いを押さえていきましょう。

対象になるのは、消費者向けのサービスに限りません。社内向けの業務システムでも、管理画面の検索フィルターや、チケット管理システムの自動下書き保存、一覧画面の絞り込み表示など、当てはまる場面は少なくないのです。利用者数がそれほど多くない社内システムでも、同時にアクセスする人数や画面の重さによっては、間引きの有無が体感の差につながります。

MDN Web Docsの解説では、デバウンスの動きを3つの局面に分けて説明しています。「最初の呼び出し」「猶予期間」「猶予期間が過ぎたあとの実行」という流れです。呼び出しのたびに猶予期間がリセットされ、静かな状態が続いて初めて処理が走る、という流れがイメージしやすくなるでしょう。

どちらも新しい技術ではなく、ブラウザ上でのイベント処理として以前から使われてきた考え方です。フレームワークや標準APIが進化した現在でも、イベントの発生源を間引くという役割そのものは変わっていません。

デバウンスの仕組みと使いどころ

デバウンスとは、連続して発生するイベントの呼び出しをいったん保留し、一定時間イベントが発生しなくなったタイミングで、最後の1回だけ処理を実行する仕組みです。エレベーターの扉が、人が乗り込むたびに閉まりかけては開き直す様子にたとえられることがあります。

典型的な使いどころは、検索フォームのオートコンプリートです。入力のたびにAPIを呼ぶのではなく、入力が止まってから一定時間(wait時間)待ち、そこで初めて検索リクエストを送ります。フォーム入力の確定処理や、入力内容のバリデーションチェックにも同じ考え方が使えるでしょう。

検索以外にも、確定を待ってから処理したい場面は少なくありません。住所入力に合わせた位置情報の問い合わせや、入力内容を自動で下書き保存するオートセーブ機能、タグ入力のサジェスト表示などが挙げられます。いずれも、入力の途中経過ではなく最終的な値がほしい、という共通点があるでしょう。

実装では、待つ時間の長さに加えて、区間の始まり(leading)で実行するか、終わり(trailing)で実行するかを選べる場合があります。ライブラリの既定設定では、区間の終わりで1回だけ実行する動きになっていることが多いようです。

wait時間の長さは、体感に直結します。短くしすぎると連続入力の途中でも実行されてしまい、間引きの効果が薄れてしまうのです。反対に長くしすぎると、入力を終えてから結果が表示されるまでの待ち時間が目立ち、使いにくく感じられることもあります。

実務上は、保留中の呼び出しを取り消すcancelメソッドや、即座に実行させるflushメソッドが用意されているライブラリも珍しくありません。画面遷移の直前に保留分を後始末する、といった細かな制御にも役立ちます。

具体的な流れをイメージしてみましょう。利用者が「クラウド移行」と打ち込むあいだに何度もキー入力があったとしても、デバウンスを使えば検索APIの呼び出しは1回で済みます。入力が止まってから一定時間が経過した時点で、最後に入力された文字列だけでリクエストが送られるためです。

CSS-Tricksの解説では、ブラウザの幅をドラッグしてリサイズしている最中に多数のresizeイベントが発生する例が紹介されています。リサイズが終わった最終的な値だけ知りたい場面では、デバウンスが向くと紹介されています。

デバウンスに共通しているのは、「今すぐの反応」よりも「落ち着いたあとの正確な1回」を優先する考え方だといえます。裏を返せば、途中経過を細かく画面へ反映したい処理には不向きだという点も、あわせて押さえておきたいところです。次の章では、逆に「経過を追い続ける」ことを優先するスロットルを見ていきましょう。

スロットルの仕組みと使いどころ

スロットルとは、連続して発生するイベントに対し、一定間隔ごとに1回だけ処理を実行し、それ以外の呼び出しを間引く仕組みです。デバウンスが「呼び出しが止まるまで待つ」のに対し、スロットルは「呼び出しが続いていても、決めた間隔ではきちんと実行する」点が異なります。

典型的な使いどころは、スクロールイベントの監視です。MDNのドキュメントでも、scrollイベントは高い頻度で発火すると説明されています。DOM操作のような負荷の高い処理は、イベントハンドラーの中でそのまま実行しないよう案内されているのです。ウィンドウのリサイズや、マウス移動に連動する描画更新も同様の考え方で扱えます。

スクロール監視のほかにも、同じ考え方が使える場面があります。無限スクロールで次のページを読み込むタイミングの判定、ドラッグ操作中の座標計算、マウスの動きに合わせたツールチップの位置更新などです。イベントが途切れない間も一定周期で処理を挟みたい、という場面で共通して選ばれる手法といえます。

スロットルにも、区間の始まりで実行するか終わりで実行するかという選択肢があります。スクロール位置の表示のように、動きに追従させたい処理では、区間の始まりで実行する設定が選ばれやすい傾向にあります。

スクロール位置の判定に絞るなら、しきい値を指定して監視できるIntersectionObserverという別の仕組みを使う方法もあります。要素が画面内に入ったかどうかだけを知りたい場合は、スロットルを自前で書くよりも扱いやすいことがあるでしょう。

MDN Web Docsのscrollイベント最適化の解説には、具体例が示されています。直近のスクロール位置を変数に保持しておき、一定時間ごとにsetTimeoutで処理を実行するという内容です。あわせて、requestAnimationFrameはscrollイベントと同じ頻度で呼ばれてしまうため、間引きの目的では効果が薄いとも注意されているのです。

スクロール中に連続して発生するイベントの数は、環境によって変わります。スロットルを使えば、そのすべてに反応するのではなく、決めた間隔ごとにだけ処理を実行し、残りを間引けるのです。

スロットルに共通しているのは、「経過を追い続けながらも、負荷は一定に抑える」という考え方です。デバウンスとは優先する価値が異なるため、次の章で両者を並べて対比してみましょう。

デバウンスとスロットルの使い分け

どちらの手法も「呼び出しを間引く」点は共通していますが、間引き方が異なるため、向く場面も変わってきます。下の図は、同じイベントの連なりに対して、デバウンスとスロットルがそれぞれどのタイミングで処理を実行するかを対比したものです。

図
図:連続して発生するイベントに対し、デバウンスは最後の1回だけ、スロットルは一定間隔ごとに実行する

図の通り、デバウンスは呼び出しが途切れてから最後の1回だけ実行するため、入力確定のように「最終的な値だけ知りたい」場面に向いています。スロットルは呼び出しが続いている間も一定間隔で実行し続けるため、スクロール位置の追従のように「経過を追いかけたい」場面に向いているといえるでしょう。同じ画面の要件でも、間引き方を取り違えると狙った体感にならないため、企画段階でどちらを想定しているかをすり合わせておくと手戻りを防ぎやすくなります。

観点 デバウンス スロットル
実行タイミング 呼び出しが止まってから一定時間後に、最後の1回だけ実行します。
区間の終わり(trailing)で実行する既定設定が多く見られます。
呼び出しが続いていても、一定間隔ごとに1回は実行し続けます。
区間の始まりで実行するか、終わりで実行するかを選べる場合があります。
向く場面 検索オートコンプリートやフォーム確定、送信ボタンの二重クリック対策などに向いています。
最終的な値や最後の操作だけを拾いたい場面で使われます。
スクロール監視やウィンドウのリサイズ処理、マウス移動に連動する描画更新などに向いています。
操作の経過を一定周期で追いかけたい場面で使われます。
体感 入力を止めるまで反応が保留されるため、操作直後は画面が動かないように見えることがあります。 操作中も一定周期で反応が返ってくるため、動きに追従している印象を受けやすくなります。
実装のしやすさ Lodashなどのライブラリのdebounce関数を使えば、待ち時間の指定だけで導入できます。 同じくthrottle関数を使えば、間隔の指定だけで導入できます。

選択に迷ったときは、「最終的な値だけで十分か」「経過を追い続ける必要があるか」を自問するとよいでしょう。前者であればデバウンス、後者であればスロットルが候補になります。

検索フォームでは、両方を組み合わせる画面設計も見られます。入力中はスロットルで軽い候補表示を一定周期ごとに更新しつつ、確定後の本検索はデバウンスで最後の1回だけAPIを呼ぶ、といった組み方です。目的の異なる更新を同じ入力欄で扱う場合は、こうした組み合わせも選択肢になるでしょう。

ボタンの二重クリック対策にも、この考え方が使えます。送信ボタンを押した直後の一定時間、再クリックを受け付けないようにする実装は、区間の始まりで1回だけ処理を通すデバウンス(leading方式)の応用です。ボタンを一時的に無効化し、レスポンスを受け取ってから再度有効にする実装とも、狙いは同じでしょう。二重送信を防ぐという目的に対しては、どちらの実装を選んでも構いません。

間引きは通信量を抑える一方で、キーボード操作を主に使う利用者にとっては、反応までの間が長く感じられることもあります。画面の用途によっては、間引きの度合いと操作感のバランスを、複数の利用シーンで確かめておきたいところです。

発注・レビューで押さえる点

デバウンスとスロットルの実装そのものは、いまはライブラリを使うのが一般的です。JavaScriptのユーティリティライブラリであるLodashは、debounce関数とthrottle関数を提供しています。待ち時間やleading・trailingの挙動は、オプションで指定できるでしょう。発注やレビューの場では、実装の細部よりも設定の妥当性を見る視点が役立ちます。

自前で待ち時間の管理やタイマーの解除を実装すると、画面遷移時の後始末が漏れたり、タイマーが二重に走ってしまったりする不具合を招きやすくなります。ライブラリに任せれば、そうした細部の作り込みと検証の手間を省けるでしょう。

過剰なAPI呼び出しが残っていないか

検索欄や入力補完の画面で、1文字ごとにAPIが呼ばれる作りのまま残っていないかは、確認しておきたい点です。通信のログやブラウザのネットワークタブを見れば、入力中に何回リクエストが飛んでいるかをすぐに確認できます。間引きが効いていない実装を放置すると、利用者が増えるほど無駄な通信が積み重なり、サーバー費用や応答遅延として跳ね返ってきます。

待ち時間・間隔の設定値が画面に合っているか

デバウンスの待ち時間やスロットルの間隔を誤ると、短すぎれば間引きの効果が薄れ、長すぎれば操作への反応が鈍く感じられます。画面ごとの操作感を実際に触って確かめ、値を調整してもらえるかどうかは、委託先を選ぶ際の観点になるでしょう。イベントの発生源ごとに適切な手法を選び分ける知識と、画面ごとに値をすり合わせる工程の両方が要ります。

ユーザー体験への影響を確かめる

間引きは通信量や処理負荷を抑える一方で、反応が遅れたと感じさせるおそれも抱えています。入力中にローディング表示を出す、確定前後で見た目を変えるといった工夫と合わせて設計されているかも、レビューの観点に加えておくとよいでしょう。実装と検証をあわせて外部パートナーに依頼する進め方も、選択肢の一つです。

実機・実回線でテストして値をすり合わせる

設定した待ち時間や間隔が画面に合っているかは、開発環境だけでは分かりにくいものです。実際に使われる端末や回線条件に近い状態でも動作を確かめてもらえるかを、委託先を選ぶ際の観点に加えておくとよいでしょう。回線が遅い環境ほど、間引きすぎによる反応の鈍さが目立ちやすくなります。

呼び出し回数を計測できる仕組みがあるか

設定した値が実際に効いているかどうかは、感覚だけで判断せず、通信回数の推移を計測して確かめたいところです。ブラウザの開発者ツールに加え、アクセス解析やAPIサーバーのログで呼び出し回数の変化を追える仕組みがあれば、リリース後の見直しもしやすくなります。設計・実装・検証を別々の担当が分担する体制では、こうした計測結果の共有ルールも、事前に決めておくとよいでしょう。

ここまでの観点を発注前のチェックリストとしてまとめると、次のようになります。過剰な呼び出しの有無、待ち時間・間隔の妥当性、ユーザー体験への影響、実機・実回線での検証、呼び出し回数を追える計測の仕組み、という5点です。すべてを自社だけで確認するのが難しい場合は、外部パートナーに実装とあわせて検証を依頼する進め方も現実的な選択肢になるでしょう。

まとめ

ここまで、デバウンスとスロットルという2つの間引き手法を整理してきました。要点を3つに集約すると、次のとおりです。第一に、両者とも短時間に連続するイベントの呼び出しを間引く点は共通しています。第二に、間引き方には「最後の1回だけ」と「一定間隔ごとに1回」という違いがあります。第三に、実装はライブラリに任せ、発注・レビューでは設定値と体感の妥当性を確かめる姿勢が大切になるでしょう。

  • デバウンスとスロットルは、短時間に連続するイベントの呼び出しを間引き、過剰な実行を抑える2つの制御手法である。
  • デバウンスは呼び出しが止まってから最後の1回を実行し、検索オートコンプリートやフォーム確定に向く。
  • スロットルは呼び出しが続いていても一定間隔ごとに実行し、スクロール監視やリサイズ処理に向く。
  • レートリミットやバックプレッシャーはサーバー側の流量制御であり、クライアント側のイベント間引きとは層が異なる。
  • 実装はライブラリの利用が一般的で、発注・レビューでは待ち時間の設定値とユーザー体験への影響を確かめたい。

LASSICに相談するメリット

どの画面でデバウンス・スロットルを使い、待ち時間や間隔をどう設定するかは、通信量と操作感の両方を見なければ判断しにくい設計事項です。「検索や入力補完の通信量を抑えたいが、設定値の目安が分からない」「スクロールやリサイズ処理が重く感じられる」といった悩みは少なくありません。フロントエンドの実装知識と業務要件の両方を踏まえた整理が欠かせない領域です。LASSICでは、要件定義の段階から画面設計、フロントエンド実装、公開済みシステムの見直しまでを一貫してご相談いただけます。既存画面の通信ログを確認し、間引きが効いていない箇所を洗い出すところから着手することもできるでしょう。実機・実回線での動作確認まで含めて支援します。まずは気になる画面の動きを確認するところからでも対応が可能です。

よくある質問

デバウンスとスロットルは、併用できますか。

併用できます。たとえば検索画面では、入力欄にデバウンスを使い、確定後の値だけでAPIを呼ぶ形が定番です。結果一覧のスクロール監視には、スロットルを使うといった組み合わせがよく見られます。目的が異なる処理を同じ画面の中で扱う場合は、イベントごとに手法を選び分けるのが実務的な進め方です。1つの画面に複数の間引き処理が混在しても、それぞれの役割さえ明確にしておけば扱いにくくはなりません。

待ち時間や間隔は、どのくらいに設定すればよいですか。

画面の用途によって適切な値は変わるため、決まった数値はありません。短すぎると間引きの効果が薄れ、長すぎると操作への反応が鈍く感じられるため、実際の画面を操作しながら体感を確かめて調整するのが現実的です。ライブラリの既定値をまず試し、必要に応じて画面ごとに見直す進め方が扱いやすいでしょう。回線が遅い環境で試すと、値の妥当性をより厳しく確認できます。

レートリミットやバックプレッシャーとは、どう違いますか。

レートリミットやバックプレッシャーは、主にサーバー側で受信リクエストの流量を制御する仕組みです。一方デバウンスとスロットルは、主にフロントエンドやクライアント側でイベントの発生源そのものを間引く手法であり、扱う層が異なります。両方を組み合わせて設計するシステムも珍しくないのです。クライアント側で間引いてもなお集中するリクエストへの備えとして、サーバー側の制御をあわせて用意する構成もよく見られます。

実装は自前で書く必要がありますか。

自前で書く必要はなく、ライブラリを使うのが一般的です。JavaScriptのユーティリティライブラリであるLodashは、debounce関数とthrottle関数を提供しています。待ち時間やleading・trailingの挙動は、オプションで指定できます。フレームワーク側に同等の仕組みが用意されている場合は、そちらを使う選択肢もあるでしょう。自前実装は、タイマーの後始末漏れなど細かな不具合を招きやすいため、既存の実装を活用するほうが手堅い進め方です。

著者:テレリモ総研編集部 鈴木 亮佑

LASSICでは、国内ニアショア開発体制を活かし、フロントエンドのイベント制御を含む画面設計から実装、公開済みシステムの見直しまでを一貫して支援する体制です。要件定義の段階から実装、テスト、リリース後の運用・保守まで、工程を分けずに任せられる点も強みでしょう。実装だけでなく、実機・実回線での動作検証まで含めて対応できるのが特徴です。設計・実装・検証の担当を分けずに進められるため、値のすり合わせにかかるやり取りの手間も抑えられます。検索・スクロールまわりの通信量や操作感でお困りの際も、ご相談いただけます。


フロントエンド開発・システム開発のご相談はLASSICへ

元請(プライムベンダー)として、要件整理からご提案・開発・保守までお手伝いします。まずはお気軽にご相談ください。

無料相談はこちら

ご不明な点はお問い合わせフォームからもご連絡いただけます。

出典


View