Sådan forbedrer du søgeydelsen ved at reagere med debouncing

I React, når du implementerer søgefunktionaliteten, kalder onChange-handleren søgefunktionen, hver gang brugeren skriver inde i inputfeltet. Denne tilgang kan forårsage ydeevneproblemer, især hvis du foretager API-kald eller forespørger i databasen. Hyppige opkald til søgefunktionen kan overbelaste webserveren, hvilket kan føre til nedbrud eller ikke-reagerende brugergrænseflade. Debouncing løser dette problem.

Hvad er debouncing?

Typisk implementerer du søgefunktionaliteten i React ved at kalde en onChange-handlerfunktion ved hvert tastetryk som vist nedenfor:

 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..."
    />
  );
}

Selvom dette virker, kan opkaldet til backend for at opdatere søgeresultater ved hvert tastetryk blive dyrt. For eksempel, hvis du søgte efter “webdev”, ville applikationen sende en anmodning til backend med værdierne “w”, “we”, “web” og så videre.

Debouncing er en teknik, der virker ved at forsinke udførelsen af ​​en funktion, indtil en forsinkelsesperiode er udløbet. Debounce-funktionen registrerer hver gang brugeren taster og forhindrer opkaldet til søgebehandleren, indtil forsinkelsen er udløbet. Hvis brugeren fortsætter med at skrive inden for forsinkelsesperioden, nulstilles timeren, og React kalder funktionen igen for den nye forsinkelse. Denne proces fortsætter, indtil brugeren holder pause med at skrive.

  Sådan tilsluttes AirPods til en iPhone

Ved at vente på, at brugerne pauser indtastningen, sikrer debouncing, at din applikation kun foretager de nødvendige søgeanmodninger, hvilket reducerer serverbelastningen.

Sådan debounce søgning i React

Der er flere biblioteker, du kan bruge til at implementere debounce. Du kan også vælge at implementere det selv fra bunden ved hjælp af JavaScripts setTimeout og clearTimeout funktioner.

Denne artikel bruger debounce-funktionen fra lodash-biblioteket.

Forudsat at du har et React-projekt klar, skal du oprette en ny komponent kaldet Søg. Hvis du ikke har et fungerende projekt, skal du oprette en React-app ved hjælp af værktøjet Create React-app.

I søgekomponentfilen skal du kopiere følgende kode for at oprette en søgeindtastningsboks, der kalder en behandlerfunktion ved hvert tastetryk.

 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..."
    />
  );
}

For at debounce handleSearch-funktionen skal du videregive den til debounce-funktionen fra 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..."
    />
  );
}

I debounce-funktionen sender du den funktion, du vil forsinke, dvs. handleSearch-funktionen, og forsinkelsestiden i millisekunder, dvs. 500ms.

  Sådan slår du lyden fra for andre personer i Google Meet

Selvom ovenstående kode burde forsinke opkaldet til handleSearch-anmodningen, indtil brugeren holder pause med at skrive, virker den ikke i React. Vi forklarer hvorfor i det følgende afsnit.

Debouncing og gengivelser

Denne applikation bruger en kontrolleret input. Dette betyder, at tilstandsværdien styrer værdien af ​​inputtet; hver gang en bruger indtaster i søgefeltet React opdaterer tilstanden.

I React, når en tilstandsværdi ændres, gengiver React komponenten og udfører alle funktionerne i den.

I ovenstående søgekomponent, når komponenten genrenderes, udfører React debounce-funktionen. Funktionen opretter en ny timer, der holder styr på forsinkelsen, og den gamle timer sidder i hukommelsen. Når tiden er gået, aktiverer den søgefunktionen. Det betyder, at søgefunktionen aldrig debounces, den er forsinket med 500 ms. Denne cyklus gentages ved hver gengivelse – funktionen opretter en ny timer, den gamle timer udløber, og derefter kalder den søgefunktionen

For at debounce-funktionen skal fungere, skal du kun kalde den én gang. Du kan gøre dette ved at kalde debounce-funktionen uden for komponenten eller ved at bruge memoiseringsteknikken. På denne måde, selvom komponenten genrenderes, vil React ikke udføre den igen.

Definition af debounce-funktionen uden for søgekomponenten

Flyt debounce-funktionen uden for søgekomponenten som vist nedenfor:

 import debounce from "lodash.debounce"

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

const debouncedSearch = debounce(handleSearch, 500);

Kald nu debouncedSearch i søgekomponenten og indtast søgeordet.

 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..."
    />
  );
}

Søgefunktionen vil først blive kaldt, når forsinkelsesperioden er udløbet.

  Du kan sikkert deaktivere eller afinstallere disse forudinstallerede apps på Samsung-telefoner

Lagring af Debounce-funktionen

Memoizing refererer til at cache resultaterne af en funktion og genbruge dem, når du kalder funktionen med de samme argumenter.

For at huske debounce-funktionen skal du bruge useMemo-krogen.

 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..."
    />
  );
}

Bemærk, at du også har pakket handleSearch-funktionen ind i en useCallback-hook for at sikre, at React kun kalder den én gang. Uden useCallback-hook ville React udføre handleSearch-funktionen med hver gengivelse, hvilket ville ændre afhængighederne af useMemo-hook, hvilket igen ville kalde debounce-funktionen.

Nu vil React kun kalde debounce-funktionen, hvis handleSearch-funktionen eller forsinkelsestiden ændres.

Optimer søgning med Debounce

Nogle gange kan nedsættelse af farten være bedre for ydeevnen. Når du håndterer søgeopgaver, især med dyre database- eller API-kald, er brug af en debounce-funktion vejen at gå. Denne funktion introducerer en forsinkelse før afsendelse af backend-anmodninger.

Det hjælper med at reducere antallet af anmodninger til serveren, da det først sender anmodningen efter forsinkelsen er udløbet, og brugeren har holdt pause med at skrive. På denne måde bliver serveren ikke overbelastet med for mange anmodninger, og ydeevnen forbliver effektiv.