Hvordan forbedre søkeytelsen ved å reagere med debouncing

I React, når du implementerer søkefunksjonaliteten, kaller onChange-behandleren søkefunksjonen hver gang brukeren skriver inn i inndataboksen. Denne tilnærmingen kan forårsake ytelsesproblemer, spesielt hvis du foretar API-anrop eller spør etter databasen. Hyppige anrop til søkefunksjonen kan overbelaste webserveren, noe som kan føre til krasjer eller ikke-svarende brukergrensesnitt. Debouncing løser dette problemet.

Hva er debouncing?

Vanligvis implementerer du søkefunksjonaliteten i React ved å kalle en onChange-behandlerfunksjon ved hvert tastetrykk 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..."
    />
  );
}

Selv om dette fungerer, kan oppfordringen til backend for å oppdatere søkeresultater ved hvert tastetrykk bli dyrt. For eksempel, hvis du søkte etter «webdev», ville applikasjonen sende en forespørsel til backend med verdiene «w», «we», «web» og så videre.

Debouncing er en teknikk som fungerer ved å utsette utførelsen av en funksjon til en forsinkelsesperiode har gått. Debounce-funksjonen oppdager hver gang brukeren skriver og forhindrer anropet til søkebehandleren inntil forsinkelsen har utløpt. Hvis brukeren fortsetter å skrive innenfor forsinkelsesperioden, tilbakestilles timeren og React kaller opp funksjonen igjen for den nye forsinkelsen. Denne prosessen fortsetter til brukeren stopper å skrive.

  Hvordan speile en telefon, Mac eller PC til en Fire TV Stick

Ved å vente på at brukerne skal sette skrivingen på pause, sikrer debouncing at applikasjonen din bare gjør de nødvendige søkeforespørslene og reduserer dermed serverbelastningen.

Hvordan avvise søk i React

Det er flere biblioteker du kan bruke til å implementere debounce. Du kan også velge å implementere det selv fra bunnen av ved å bruke JavaScripts setTimeout- og clearTimeout-funksjoner.

Denne artikkelen bruker debounce-funksjonen fra lodash-biblioteket.

Forutsatt at du har et React-prosjekt klart, lag en ny komponent kalt Søk. Hvis du ikke har et fungerende prosjekt, kan du opprette en React-app ved å bruke verktøyet create React-appen.

I søkekomponentfilen kopierer du følgende kode for å lage en søkeinndataboks som kaller opp en behandlerfunksjon ved hvert tastetrykk.

 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 å avvise handleSearch-funksjonen, send den til debounce-funksjonen 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-funksjonen sender du inn funksjonen du vil forsinke, dvs. handleSearch-funksjonen, og forsinkelsestiden i millisekunder, dvs. 500ms.

  Slik aktiverer du materiale du designer på Chromebooken din

Selv om koden ovenfor bør forsinke anropet til handleSearch-forespørselen til brukeren pauser å skrive, fungerer den ikke i React. Vi vil forklare hvorfor i den følgende delen.

Debouncing og gjengivelser

Denne applikasjonen bruker en kontrollert inngang. Dette betyr at tilstandsverdien kontrollerer verdien av inngangen; hver gang en bruker skriver i søkefeltet oppdaterer React tilstanden.

I React, når en tilstandsverdi endres, gjengir React komponenten og utfører alle funksjonene i den.

I søkekomponenten ovenfor, når komponenten gjengis, utfører React debounce-funksjonen. Funksjonen lager en ny timer som holder styr på forsinkelsen og den gamle timeren sitter i minnet. Når tiden går ut, aktiverer den søkefunksjonen. Dette betyr at søkefunksjonen aldri blir avvist, den er forsinket med 500 ms. Denne syklusen gjentas for hver gjengivelse – funksjonen oppretter en ny tidtaker, den gamle tidtakeren utløper og deretter kaller den søkefunksjonen

For at debounce-funksjonen skal fungere, må du bare ringe den én gang. Du kan gjøre dette ved å kalle debounce-funksjonen utenfor komponenten eller ved å bruke memoiseringsteknikken. På denne måten, selv om komponenten gjengir, vil ikke React kjøre den igjen.

Definere debounce-funksjonen utenfor søkekomponenten

Flytt debounce-funksjonen utenfor søkekomponenten som vist nedenfor:

 import debounce from "lodash.debounce"

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

const debouncedSearch = debounce(handleSearch, 500);

Nå, i søkekomponenten, ring debouncedSearch og send inn søkeordet.

 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økefunksjonen vil først bli kalt opp etter at forsinkelsesperioden er utløpt.

  Hva er Scareware og hvordan du kan redde deg selv fra det?

Lagre Debounce-funksjonen

Memoizing refererer til å bufre resultatene av en funksjon og gjenbruke dem når du kaller funksjonen med de samme argumentene.

For å huske debounce-funksjonen, bruk useMemo-kroken.

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

Merk at du også har pakket handleSearch-funksjonen inn i en useCallback-hook for å sikre at React bare ringer den én gang. Uten useCallback-kroken, ville React utføre handleSearch-funksjonen med hver gjengivelse, noe som gjør at avhengighetene til useMemo-kroken endres, som igjen vil kalle debounce-funksjonen.

Nå vil React bare kalle opp debounce-funksjonen hvis handleSearch-funksjonen eller forsinkelsestiden endres.

Optimaliser søk med Debounce

Noen ganger kan nedbremsing være bedre for ytelsen. Når du håndterer søkeoppgaver, spesielt med dyre database- eller API-anrop, er bruk av en debounce-funksjon veien å gå. Denne funksjonen introduserer en forsinkelse før sending av backend-forespørsler.

Det bidrar til å redusere antallet forespørsler som sendes til serveren, siden den bare sender forespørselen etter at forsinkelsen har gått ut og brukeren har stoppet skrivingen. På denne måten blir ikke serveren overbelastet med for mange forespørsler, og ytelsen forblir effektiv.