Contents

如何透過去抖動來提高 React 中的搜尋效能

在 React 中,實作搜尋功能時,每次使用者在輸入框中鍵入內容時,onChange 處理程序都會呼叫搜尋函數。這種方法可能會導致效能問題,尤其是在進行 API 呼叫或查詢資料庫時。頻繁地呼叫搜尋功能可能會使 Web 伺服器過載,從而導致崩潰或 UI 無回應。去抖動解決了這個問題。

什麼是去抖?

在 React 中搜尋功能的典型實作中,每次按鍵時通常都會呼叫 onChange 處理函數,如下所示:

 import { useState } from "react";

export default function Search() {
  const [searchTerm, setSearchTerm] = useState("");

  const handleSearch = () => {
    console.log("Search for:", searchTerm);
  };

  const handleChange = (e) => {
    setSearchTerm(e.target.value);
    // Calls search function
    handleSearch();
  };

  return (
    <input
      onChange={handleChange}
      value={searchTerm}
      placeholder="Search here..."/>
  );
}

為了優化效能,重要的是要考慮到,在鍵入「webdev」等關鍵字時,透過呼叫後端來頻繁更新搜尋結果可能會變得昂貴。在這種情況下,每次輸入新字元時,應用程式都會向後端發送請求,包括「w」、「we」、「web」等字元。

去抖動涉及推遲函數的執行,直到自上次呼叫以來指定的時間範圍過去。在這種情況下,只有當使用者在指定的時間間隔後停止輸入時,才會觸發去抖動功能。如果在指定時間內發生進一步的輸入,則計時器重設並啟動另一輪處理。只要沒有進行額外的按鍵輸入,這個循環就會重複,一旦使用者停止打字活動,這個循環就會終止。

去抖動允許應用程式透過延遲伺服器請求直到使用者停止輸入資料來有效地管理伺服器請求,從而最大限度地減少不必要的搜尋並減輕伺服器的壓力。

如何在 React 中反跳搜索

當尋求在 Web 應用程式中合併去抖動功能時,存在多個提供此功能的現有程式庫。或者,人們可以選擇利用 JavaScript 的「setTimeout」和「clearTimeout」方法從頭開始建立去抖器演算法。

本文使用 Lodash 程式庫提供的去抖功能,該程式庫是一種流行的 JavaScript 實用程序,為資料操作和操作優化提供了廣泛的功能。

為了啟動在現有 React 專案中開發搜尋功能或建立新專案的流程,有必要先建立一個名為「Search」的新穎元件。這可以透過利用現有的 React 應用程式或使用「建立 React 應用程式」實用程式來產生功能齊全的 React 環境來實現。

在搜尋元件檔案中,可以利用提供的程式碼片段產生搜尋輸入字段,該字段將在每次按鍵時執行指定的回調函數。

 import { useState } from "react";

export default function Search() {
  const [searchTerm, setSearchTerm] = useState("");

  const handleSearch = () => {
    console.log("Search for:", searchTerm);
  };

  const handleChange = (e) => {
    setSearchTerm(e.target.value);
    // Calls search function
    handleSearch();
  };

  return (
    <input
      onChange={handleChange}
      value={searchTerm}
      placeholder="Search here..."/>
  );
}

要使用 Lodash 函式庫提供的「debounce」函式延遲「handleSearch」函式的執行,可以將該函式作為參數傳遞給「debounce」方法。這將確保函數在給定的時間內僅執行一次,之後該時間範圍內的任何後續呼叫都將被忽略,直到等待期到期。

 import debounce from "lodash.debounce";
import { useState } from "react";

export default function Search() {
  const [searchTerm, setSearchTerm] = useState("");

  const handleSearch = () => {
    console.log("Search for:", searchTerm);
  };
  const debouncedSearch = debounce(handleSearch, 1000);

  const handleChange = (e) => {
    setSearchTerm(e.target.value);
    // Calls search function
    debouncedSearch();
  };

  return (
    <input
      onChange={handleChange}
      value={searchTerm}
      placeholder="Search here..."/>
  );
}

在去抖動機制的實作中,我們引入了一個自訂版本的handleSearch函數,接受它作為參數以及指定的時間間隔,即500毫秒,作為觸發該函數延遲執行的閾值。

上述程式碼預計會延後handleSearch函數的執行,直到使用者停止輸入資料;但是,此功能在 React 框架內無法如預期運作。造成這種差異的原因將在後續部分進一步探討。

去搖晃和重新渲染

本申請採用調節輸入,其中系統的現狀決定透過搜尋欄提供為輸出的內容。使用者在這個特定介面中輸入的每次擊鍵,React 都會相應地對狀態配置進行修改。

React 是一個流行的 JavaScript 函式庫,用於建立使用者介面。每當 React 元件中的狀態值發生變化時,整個元件就會重新渲染,這涉及從頭到尾再次執行其所有函數。這允許對介面進行動態更新,而無需刷新整頁。

前面提到的搜尋元件會經歷重新渲染,在此期間 React 會啟動去抖動機制。創建了一種新穎的計時器來監視延遲,同時現有計時器在系統記憶體中保持活動狀態。後者到期後,延遲500毫秒後觸發搜尋功能。因此,這個序列在每次渲染時都會重複出現,因為新的計時器優先於前一個計時器,而較舊的計時器隨後在重複呼叫搜尋功能之前完成其終止週期。

為了確保去抖函數在 React 元件中按預期運行,將其執行限制為單一實例非常重要。實現這一目標的一種方法涉及結合使用記憶技術和去抖動功能。這樣做,即使元件重新渲染,debounced函數也不會被重複執行。

在搜尋元件外部定義去抖函數

考慮將延遲執行機制(例如“debounce”)重新定位到“Search”元件之外的位置,如下面提供的範例所示:

 import debounce from "lodash.debounce"

const handleSearch = (searchTerm) => {
  console.log("Search for:", searchTerm);
};

const debouncedSearch = debounce(handleSearch, 500);

在我們專案的搜尋元件的當前迭代中,我們將透過呼叫「debouncedSearch」方法並向其提供搜尋查詢作為參數來實現「search」函數的去抖版本。

 export default function Search() {
  const [searchTerm, setSearchTerm] = useState("");

  const handleChange = (e) => {
    setSearchTerm(e.target.value);
    // Calls search function
    debouncedSearch(searchTerm);
  };

  return (
    <input
      onChange={handleChange}
      value={searchTerm}
      placeholder="Search here..."/>
  );
}

搜尋功能的功能取決於預定義時間間隔的到期,此時它將被呼叫。

記得去抖動功能

記憶化涉及儲存特定函數在接收到特定輸入時產生的輸出,以便在使用相同參數再次呼叫函數時可以輕鬆檢索和利用該輸出。該技術被用作最小化計算費用的最佳化策略,特別是在涉及重複計算的情況下。

為了利用 React 的 Memoization 機制有效地快取和推遲去抖動函數的執行,請結合使用 useMemo Hook 和適當的實作策略來實現所需的去抖動效果。

 import debounce from "lodash.debounce";
import { useCallback, useMemo, useState } from "react";

export default function Search() {
  const [searchTerm, setSearchTerm] = useState("");

  const handleSearch = useCallback((searchTerm) => {
    console.log("Search for:", searchTerm);
  }, []);

  const debouncedSearch = useMemo(() => {
    return debounce(handleSearch, 500);
  }, [handleSearch]);

  const handleChange = (e) => {
    setSearchTerm(e.target.value);
    // Calls search function
    debouncedSearch(searchTerm);
  };

  return (
    <input
      onChange={handleChange}
      value={searchTerm}
      placeholder="Search here..."/>
  );
}

值得注意的是,我們將 handleSearch 函數包含在 useCallback 鉤子中,以保證 React 只會呼叫該函數一次。如果沒有 useCallback 鉤子,React 會在每次渲染過程中重複執行 handleSearch 函數,導致 useMemo 鉤子的依賴項發生變化,進而觸發 debounce 函數。

React 僅在「handleSearch」函數或延遲週期改變的情況下呼叫去抖函數。

透過反跳優化搜索

有時,放慢步伐可能會提高生產力。在搜尋操作期間涉及昂貴的資料庫或 API 查詢的情況下,使用去抖功能變得謹慎。此函數在將請求轉送到後端之前施加暫時暫停。

在網頁中實現延遲圖像載入機制可以透過限制向伺服器發出請求的頻率來顯著減輕伺服器的負擔。透過將系統配置為等到使用者暫停輸入後再發送影像請求,我們可以最大程度地減少同時處理的請求量。因此,這種方法可以保持最佳的伺服器效能,同時防止資源耗盡或回應時間延遲。