HOME / BLOG
BLOG

JavaScriptのdebounceとは?検索フォームで使う実装例

デフォルト画像

検索フォームや絞り込みUIで、入力のたびに重い処理やAPI通信を走らせると、画面がもたつきやすくなります。そこで使うのが debounce です。

debounceは、連続して発生する処理を少し待って、最後の1回だけ実行する考え方です。検索候補、絞り込み、入力チェック、リサイズ処理などでよく使います。

HTML

<label class="search-box">
  記事を検索
  <input id="keyword" type="search" placeholder="JavaScript、CSS、バスケ">
</label>

<ul id="results" class="result-list"></ul>

JavaScript

const input = document.querySelector("#keyword");
const results = document.querySelector("#results");

const posts = [
  "JavaScriptでフォーム入力を検証する方法",
  "CSS :focus-visibleの使い方",
  "バスケのピックアンドロール入門",
  "PHPでPDOのプリペアドステートメントを使う方法",
];

function debounce(callback, delay = 300) {
  let timerId;

  return (...args) => {
    clearTimeout(timerId);
    timerId = setTimeout(() => {
      callback(...args);
    }, delay);
  };
}

function render(keyword) {
  const value = keyword.trim().toLowerCase();
  const filtered = posts.filter((post) => {
    return post.toLowerCase().includes(value);
  });

  results.innerHTML = filtered
    .map((post) => `<li>${post}</li>`)
    .join("");
}

input.addEventListener("input", debounce((event) => {
  render(event.target.value);
}, 300));

render("");

debounceを入れる場面

場面理由
検索入力1文字ごとに検索処理を走らせる必要がない
API通信短時間にリクエストが増えるのを防ぐ
resize処理画面サイズ変更中の連続実行を抑える
入力プレビューユーザーが止まってから反映すると見やすい

実装の注意点

  • 短すぎるdelayは効果が薄く、長すぎると反応が遅く感じる
  • 検索UIなら200〜500msあたりから調整する
  • 送信ボタンの二重送信防止にはdebounceよりdisabled制御が向いている
  • API通信ではAbortControllerと組み合わせると古いリクエストも止めやすい

あわせて読みたい

参考資料