Contents

Hoe de zoekprestaties in React verbeteren met Debouncing

In React roept de onChange handler bij het implementeren van de zoekfunctie de zoekfunctie aan telkens wanneer de gebruiker in het invoervak typt. Deze aanpak kan prestatieproblemen veroorzaken, vooral bij API-aanroepen of query’s in de database. Veelvuldige aanroepen van de zoekfunctie kunnen de webserver overbelasten, wat kan leiden tot crashes of een niet reagerende UI. Debouncing lost dit probleem op.

Wat is debouncen?

In een typische implementatie van de zoekfunctie in React wordt meestal een onChange handler-functie aangeroepen bij elke toetsaanslag, zoals hieronder wordt geïllustreerd:

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

Om de prestaties te optimaliseren, is het belangrijk om te bedenken dat het frequent bijwerken van zoekresultaten via oproepen naar de backend duur kan worden bij het typen van trefwoorden zoals “webdev”. In dit scenario stuurt de applicatie verzoeken naar de backend telkens wanneer een nieuw teken wordt ingevoerd, inclusief tekens als “w”, “we”, “web”, enz.

Debouncen houdt in dat de uitvoering van een functie wordt uitgesteld totdat een toegewezen tijdsbestek is verstreken sinds de laatste aanroep. In dit scenario wordt de gedebounceerde functie alleen uitgevoerd als de gebruiker stopt met typen na het opgegeven interval. Als verdere invoer plaatsvindt tijdens de aangegeven periode, wordt de timer gereset en wordt een nieuwe verwerkingsronde gestart. Deze cyclus wordt herhaald zolang er geen extra toetsinvoer is en eindigt zodra de gebruiker stopt met typen.

Debouncing stelt een applicatie in staat om serververzoeken efficiënt te beheren door ze uit te stellen totdat een gebruiker geen gegevens meer invoert, waardoor onnodig zoeken wordt geminimaliseerd en de server minder wordt belast.

Hoe Debounce Search in React

Als je de debouncing-functionaliteit in een webapplicatie wilt opnemen, zijn er meerdere reeds bestaande bibliotheken die deze mogelijkheid bieden. Je kunt er ook voor kiezen om het debouncer-algoritme vanaf de grond op te bouwen met behulp van de JavaScript-methodes setTimeout en clearTimeout .

Dit artikel maakt gebruik van de debouncing-functionaliteit die wordt geleverd door de Lodash-bibliotheek, een populair JavaScript-hulpprogramma dat een breed scala aan functies biedt voor gegevensmanipulatie en optimalisatie van bewerkingen.

Om te beginnen met het ontwikkelen van een zoekfunctie binnen je bestaande React-project of door een nieuw project te maken, moet je eerst een nieuw component genaamd “Zoeken” maken. Dit kan worden bereikt door gebruik te maken van een bestaande React-toepassing of door het hulpprogramma ‘React app maken’ te gebruiken om een volledig functionele React-omgeving te genereren.

In het bestand Zoekcomponent kan het meegeleverde codefragment worden gebruikt om een zoekinvoerveld te genereren dat bij elke druk op een toets een aangewezen terugbelfunctie uitvoert.

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

Om de uitvoering van de functie handleSearch uit te stellen met behulp van de functie debounce van de Lodash-bibliotheek, kan de genoemde functie als argument worden doorgegeven aan de methode debounce . Dit zorgt ervoor dat de functie slechts één keer wordt uitgevoerd gedurende een bepaalde periode, waarna alle volgende aanroepen binnen dat tijdsbestek worden genegeerd totdat de wachtperiode afloopt.

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

Bij de implementatie van het debouncing-mechanisme introduceren we een aangepaste versie van de handleSearch functie door deze als argument te accepteren, samen met een opgegeven tijdsinterval, namelijk 500 milliseconden, dat dient als drempel voor het activeren van de uitgestelde uitvoering van de genoemde functie.

Van de bovenstaande code wordt verwacht dat deze de uitvoering van de functie handleSearch uitstelt totdat de gebruiker stopt met het invoeren van gegevens; deze functionaliteit werkt echter niet zoals bedoeld binnen het React-framework. De redenen voor deze discrepantie zullen verder worden onderzocht in de volgende paragraaf.

Debouncing en Rerenders

De huidige toepassing maakt gebruik van gereguleerde invoer, waarbij de status quo van het systeem de inhoud bepaalt die als uitvoer via de zoekbalk wordt aangeboden. Bij elke toetsaanslag die de gebruiker binnen deze specifieke interface invoert, voegt React dienovereenkomstig wijzigingen toe aan de configuratie van de status.

React is een populaire JavaScript-bibliotheek die wordt gebruikt voor het bouwen van gebruikersinterfaces. Telkens wanneer een statuswaarde in een React-component verandert, wordt de hele component opnieuw gerenderd, waarbij alle functies van begin tot eind opnieuw worden uitgevoerd. Hierdoor kan de interface dynamisch worden bijgewerkt zonder dat de pagina volledig moet worden vernieuwd.

De eerder genoemde zoekcomponent wordt opnieuw gerenderd waarbij React het debouncingmechanisme activeert. Er wordt een nieuwe timer gemaakt om de vertraging te controleren terwijl een bestaande timer actief blijft in het systeemgeheugen. Als deze afloopt, wordt de zoekfunctie geactiveerd na een uitstel van 500 milliseconden. Bijgevolg komt deze reeks bij elke rendering terug als een nieuwe timer voorrang krijgt op de vorige, waarbij de oudere timer vervolgens zijn beëindigingsperiode voltooit voordat de zoekfunctie herhaaldelijk wordt aangeroepen.

Om ervoor te zorgen dat een gedebouncede functie werkt zoals bedoeld binnen een React-component, is het belangrijk om de uitvoering ervan te beperken tot één instantie.Een benadering om dit doel te bereiken is het gebruik van een memo-techniek in combinatie met de debouncing-functie. Hierdoor wordt de debounce-functie niet herhaaldelijk uitgevoerd, zelfs niet wanneer de component opnieuw wordt gerenderd.

De debounce-functie buiten de zoekcomponent definiëren

Overweeg om het mechanisme voor uitgestelde uitvoering, zoals debounce , te verplaatsen naar een positie buiten de zoekcomponent , zoals wordt gedemonstreerd in het onderstaande voorbeeld:

 import debounce from "lodash.debounce"

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

const debouncedSearch = debounce(handleSearch, 500);

In de huidige iteratie van de Search component van ons project zullen we een gedebounced versie van de search functie implementeren door de debouncedSearch methode aan te roepen en deze te voorzien van de zoekopdracht als argument.

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

De functionaliteit van de zoekfunctie is afhankelijk van het verlopen van een vooraf gedefinieerd tijdsinterval, op welk moment de functie wordt aangeroepen.

De Debounce-functie memoïseren

Memoïseren houdt in dat de uitvoer die door een bepaalde functie wordt gegenereerd na ontvangst van specifieke invoer wordt opgeslagen, zodat deze gemakkelijk kan worden opgehaald en gebruikt als de functie opnieuw wordt aangeroepen met identieke parameters. Deze techniek wordt gebruikt als een optimalisatiestrategie voor het minimaliseren van rekenkosten, vooral als het gaat om herhalende berekeningen.

Om de uitvoering van een gedebouncede functie effectief te cachen en uit te stellen met behulp van het Memoization-mechanisme van React, gebruikt u de haak useMemo in combinatie met een geschikte implementatiestrategie voor het gewenste debouncing-effect.

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

Het is belangrijk op te merken dat we de handleSearch functie hebben ingesloten in een useCallback hook om te garanderen dat React deze functie slechts eenmaal aanroept. Zonder de useCallback hook zou React de handleSearch functie herhaaldelijk uitvoeren tijdens elk renderproces, wat zou resulteren in wijzigingen in de afhankelijkheden van de useMemo hook en bijgevolg de debounce functie zou triggeren.

React zal de gedebouncede functie alleen aanroepen in gevallen waarin de functie handleSearch of de vertragingsperiode wordt gewijzigd.

Zoeken optimaliseren met debounce

Soms kan het matigen van het tempo leiden tot een hogere productiviteit. In situaties met kostbare database- of API-query’s tijdens zoekbewerkingen is het verstandig om een debounce-functie te gebruiken. Deze functie zorgt voor een tijdelijke pauze voordat verzoeken worden doorgestuurd naar de backend.

De implementatie van een mechanisme voor het vertraagd laden van afbeeldingen in webpagina’s kan de belasting van servers aanzienlijk verlichten door de frequentie van de aanvragen te beperken. Door het systeem zo te configureren dat het wacht tot de gebruiker zijn invoer pauzeert voordat het een verzoek voor een afbeelding verstuurt, minimaliseren we het aantal verzoeken dat tegelijkertijd wordt verwerkt. Het resultaat is dat deze aanpak optimale serverprestaties handhaaft en tegelijkertijd uitputting van bronnen of vertragingen in responstijden voorkomt.