Jak zlepšit výkon vyhledávání v reakci na debouncing

V Reactu při implementaci vyhledávací funkce volá obsluha onChange vyhledávací funkci pokaždé, když uživatel zadá do vstupního pole. Tento přístup může způsobit problémy s výkonem, zejména při volání API nebo dotazování na databázi. Častá volání vyhledávací funkce mohou přetížit webový server, což vede k selhání nebo nereagujícímu uživatelskému rozhraní. Debouncing tento problém řeší.

Co je debouncing?

Obvykle implementujete funkci vyhledávání v React voláním funkce onChange handler při každém stisku klávesy, jak je znázorněno níže:

 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);
    
    handleSearch();
  };

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

I když to funguje, volání na backend k aktualizaci výsledků vyhledávání při každém stisknutí klávesy může být drahé. Pokud byste například hledali „webdev“, aplikace by backendu odeslala požadavek s hodnotami „w“, „we“, „web“ a tak dále.

Debouncing je technika, která funguje tak, že zpožďuje provedení funkce, dokud neuplyne doba zpoždění. Funkce debounce detekuje pokaždé, když uživatel zadá, a zabrání volání obslužné rutiny vyhledávání, dokud neuplyne zpoždění. Pokud uživatel pokračuje v psaní během prodlevy, časovač se vynuluje a React vyvolá funkci znovu pro nové zpoždění. Tento proces pokračuje, dokud uživatel nepozastaví psaní.

  8 nejlepších softwaru pro správu protokolů pro rychlejší odstraňování problémů

Čekáním, až uživatelé pozastaví psaní, zajistí debouncing, že vaše aplikace provede pouze nezbytné vyhledávací požadavky, čímž se sníží zatížení serveru.

Jak debounce Search v Reactu

Existuje několik knihoven, které můžete použít k implementaci debounce. Můžete se také rozhodnout implementovat ji sami od začátku pomocí funkcí setTimeout a clearTimeout v JavaScriptu.

Tento článek používá funkci debounce z knihovny lodash.

Za předpokladu, že máte připravený projekt React, vytvořte novou komponentu s názvem Search. Pokud nemáte funkční projekt, vytvořte aplikaci React pomocí nástroje pro vytvoření aplikace React.

V souboru komponenty Hledat zkopírujte následující kód, abyste vytvořili vstupní pole hledání, které při každém stisknutí klávesy volá funkci obslužné rutiny.

 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);
    
    handleSearch();
  };

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

Chcete-li odrazit funkci handleSearch, předejte ji funkci debounce z lodash.

 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);
    
    debouncedSearch();
  };

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

Ve funkci debounce předáváte funkci, kterou chcete zpozdit, tj. funkci handleSearch, a dobu zpoždění v milisekundách, tj. 500 ms.

  8 nástrojů pro snadné kombinování videí na iPhone

Zatímco výše uvedený kód by měl zpozdit volání požadavku handleSearch, dokud uživatel nepozastaví psaní, v Reactu nefunguje. Proč tomu tak je, si vysvětlíme v následující části.

Debouncing a Rerenders

Tato aplikace používá řízený vstup. To znamená, že hodnota stavu řídí hodnotu vstupu; pokaždé, když uživatel zadá do vyhledávacího pole React, aktualizuje stav.

Když se v React změní hodnota stavu, React znovu vykreslí komponentu a provede všechny funkce v ní.

Ve výše uvedené vyhledávací komponentě, když se komponenta znovu vykreslí, React spustí funkci debounce. Funkce vytvoří nový časovač, který sleduje zpoždění a starý časovač je uložen v paměti. Když uplyne jeho čas, spustí funkci vyhledávání. To znamená, že funkce vyhledávání není nikdy debounced, je zpožděna o 500 ms. Tento cyklus se opakuje při každém renderu – funkce vytvoří nový časovač, starý časovač vyprší a poté zavolá vyhledávací funkci

Aby funkce debounce fungovala, musíte ji zavolat pouze jednou. Můžete to provést voláním funkce debounce mimo komponentu nebo pomocí techniky zapamatování. Tímto způsobem, i když se komponenta znovu vykreslí, React ji znovu nespustí.

Definování funkce debounce mimo vyhledávací komponentu

Přesuňte funkci debounce mimo komponentu Search, jak je znázorněno níže:

 import debounce from "lodash.debounce"

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

const debouncedSearch = debounce(handleSearch, 500);

Nyní v komponentě Search zavolejte debouncedSearch a předejte hledaný výraz.

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

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

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

Funkce vyhledávání bude vyvolána až po uplynutí doby zpoždění.

  27 Klávesové zkratky Microsoft Access, které se musíte naučit zpaměti

Zapamatujte si funkci Debounce

Memoování se týká ukládání výsledků funkce do mezipaměti a jejich opětovného použití, když funkci voláte se stejnými argumenty.

Chcete-li si zapamatovat funkci debounce, použijte háček useMemo.

 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);
    
    debouncedSearch(searchTerm);
  };

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

Všimněte si, že jste také zabalili funkci handleSearch do háčku useCallback, abyste zajistili, že ji React zavolá pouze jednou. Bez háku useCallback by React spustil funkci handleSearch při každém opětovném vykreslení, čímž by se změnily závislosti háku useMemo, což by zase zavolalo funkci debounce.

Nyní React zavolá funkci debounce pouze v případě, že se změní funkce handleSearch nebo doba zpoždění.

Optimalizujte vyhledávání pomocí debounce

Někdy může být zpomalení lepší pro výkon. Při zpracovávání úloh vyhledávání, zejména u drahých volání databází nebo API, je použití funkce debounce tou správnou cestou. Tato funkce zavádí zpoždění před odesláním backendových požadavků.

Pomáhá snížit počet požadavků na server, protože požadavek odešle až po uplynutí prodlevy a po pozastavení psaní. Tímto způsobem se server nepřetěžuje příliš mnoha požadavky a výkon zůstává efektivní.