ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript のパフォーマンスの向上: デバウンスとスロットリングについて

JavaScript のパフォーマンスの向上: デバウンスとスロットリングについて

Susan Sarandon
Susan Sarandonオリジナル
2024-10-06 06:22:31559ブラウズ

Enhancing Performance in JavaScript: Understanding Debouncing and Throttling

目次

  • デバウンス: 戦略的な遅延
    • デバウンスの仕組み
    • デバウンスの例
  • スロットル: イベント頻度の制御
    • スロットリングの仕組み
    • スロットルの例
  • React での実装: カスタムフックを使用したデバウンスとスロットル
    • デバウンス用のカスタムフック
    • デバウンスフックの使用
    • スロットリング用のカスタムフック
    • スロットルフックの使用
  • 最終的な感想

最新の Web アプリケーション、特に検索バーへの入力、スクロール、ウィンドウのサイズ変更などのユーザー操作を伴うアプリケーションでは、パフォーマンスの最適化が非常に重要です。これらのアクションにより、短時間に多くの関数呼び出しが起動される可能性があり、パフォーマンスが低下する可能性があります。

これを軽減するために、デバウンススロットリングという 2 つの一般的な手法を使用します。これらを使用すると、関数が呼び出される速度を制御でき、よりスムーズで効率的なエクスペリエンスが得られます。

デバウンス: 戦略的な遅延

デバウンス は、最後のイベント トリガーから指定された時間が経過するまで関数の実行を遅らせます。これは、キーストロークごとに API リクエストを行うことを避けたい、検索入力などのイベントを処理する場合に特に役立ちます。

デバウンスの仕組み

API リクエストを行う前に、ユーザーが入力を停止するまで 300 ミリ秒待機する検索入力を想像してください。デバウンスを使用すると、ユーザーが入力を一時停止した後にのみ関数が実行されるようになり、不要な API 呼び出しを防ぐことができます。

デバウンスの例


function debounce(func, delay) {
  let timeout;
  return function () {
    const context = this;
    const args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(context, args), delay);
  };
}
function searchAPI() {
  console.log("API request made");
}
const debouncedSearch = debounce(searchAPI, 300);
debouncedSearch(); // Only triggers 300ms after the last call


ここでは、ユーザーが 300 ミリ秒間一時停止した場合にのみ API リクエストが行われます。

スロットル: イベント頻度の制御

デバウンスとは対照的に、スロットルは、イベントがトリガーされ続けている場合でも、指定された間隔ごとに関数が最大 1 回呼び出されることを保証します。この手法は、ウィンドウのサイズ変更やスクロールなど、イベントが継続的に発生するシナリオに最適です。

スロットルの仕組み

スロットリングにより、定義された期間 (200 ミリ秒など) 内に関数を 1 回だけ実行できるようになり、繰り返しのトリガーによって関数が圧倒されないようにすることができます。

スロットルの例


function throttle(func, limit) {
  let lastFunc;
  let lastRan;
  return function () {
    const context = this;
    const args = arguments;
    if (!lastRan) {
      func.apply(context, args);
      lastRan = Date.now();
    } else {
      clearTimeout(lastFunc);
      lastFunc = setTimeout(() => {
        if (Date.now() - lastRan >= limit) {
          func.apply(context, args);
          lastRan = Date.now();
        }
      }, limit - (Date.now() - lastRan));
    }
  };
}
function updateLayout() {
  console.log("Layout updated");
}
const throttledUpdate = throttle(updateLayout, 200);
window.addEventListener("resize", throttledUpdate);


この例では、レイアウト更新関数はウィンドウのサイズ変更中に 200ms ごとに 1 回だけ呼び出されます。

React での実装: カスタムフックを使用したデバウンスとスロットル

React では、カスタム フックを使用して、デバウンスとスロットルの機能をコンポーネント間で再利用できるようにします。これによりモジュール性が強化され、さまざまなインタラクションのパフォーマンスが最適化されます。

デバウンス用のカスタムフック


<p>import { useRef, useCallback } from "react";<br>
const useDebounce = (func, delay) => {<br>
  const timer = useRef(null);<br>
  return useCallback(<br>
    (...args) => {<br>
      if (timer.current) {<br>
        clearTimeout(timer.current);<br>
      }<br>
      timer.current = setTimeout(() => func(...args), delay);<br>
    },<br>
    [func, delay]<br>
  );<br>
};<br>
export default useDebounce;</p>




デバウンスフックの使用



<p>import React, { useState } from "react";<br>
import useDebounce from "./useDebounce";<br>
const SearchComponent = () => {<br>
  const [searchTerm, setSearchTerm] = useState("");</p>

<p>const fetchResults = (query) => {<br>
    console.log(Fetching results for </span><span class="p">${</span><span class="nx">query</span><span class="p">}</span><span class="s2">);<br>
    return new Promise((resolve) => setTimeout(resolve, 1000));<br>
  };<br>
  const debouncedFetch = useDebounce(fetchResults, 300);<br>
  const handleSearch = (e) => {<br>
    setSearchTerm(e.target.value);<br>
    debouncedFetch(e.target.value);<br>
  };<br>
  return <input value={searchTerm} onChange={handleSearch} placeholder="Search..." />;<br>
};<br>
export default SearchComponent;</p>




スロットル用カスタムフック



<p>import { useRef, useCallback } from "react";<br>
const useThrottle = (func, limit) => {<br>
  const lastRun = useRef(Date.now());<br>
  return useCallback(<br>
    (...args) => {<br>
      const now = Date.now();<br>
      if (now - lastRun.current >= limit) {<br>
        func(...args);<br>
        lastRun.current = now;<br>
      }<br>
    },<br>
    [func, limit]<br>
  );<br>
};<br>
export default useThrottle;</p>




スロットルフックの使い方



<p>import React, { useEffect } from "react";<br>
import useThrottle from "./useThrottle";</p>

<p>const ScrollComponent = () => {<br>
  const handleScroll = () => {<br>
    console.log("Scrolled!");<br>
  };<br>
  const throttledScroll = useThrottle(handleScroll, 500);<br>
  useEffect(() => {<br>
    window.addEventListener("scroll", throttledScroll);<br>
    return () => window.removeEventListener("scroll", throttledScroll);<br>
  }, [throttledScroll]);<br>
  return <div style={{ height: "200vh" }}>Scroll down to see the effect</div>;<br>
};<br>
export default ScrollComponent;</p>




最終的な考え

デバウンススロットルの両方は、最新のアプリケーションのパフォーマンスを向上させるために不可欠なテクニックです。デバウンスは検索フィールドなどの入力に最適ですが、スロットルはスクロールなどの高頻度イベントに最適です。 useDebounce や useThrottle などの React のカスタム フックを使用すると、これらの最適化をアプリ全体に簡単に実装できるようになり、より効率的で応答性の高いエクスペリエンスが保証されます。

以上がJavaScript のパフォーマンスの向上: デバウンスとスロットリングについての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。