Cum să îmbunătățiți performanța căutării în React With Debouncing

În React, atunci când implementează funcționalitatea de căutare, handlerul onChange apelează funcția de căutare de fiecare dată când utilizatorul tasta în interiorul casetei de introducere. Această abordare poate cauza probleme de performanță, mai ales dacă se efectuează apeluri API sau se interogează baza de date. Apelurile frecvente la funcția de căutare pot supraîncărca serverul web, ceea ce duce la blocări sau interfața de utilizare care nu răspunde. Debouncing rezolvă această problemă.

Ce este Debouncing?

De obicei, implementați funcționalitatea de căutare în React apelând o funcție de gestionare onChange la fiecare apăsare a tastei, așa cum se arată mai jos:

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

În timp ce acest lucru funcționează, apelul către backend pentru a actualiza rezultatele căutării la fiecare apăsare de tastă poate deveni costisitor. De exemplu, dacă căutați „webdev”, aplicația ar trimite o solicitare către backend cu valorile „w”, „we”, „web” și așa mai departe.

Debouncing este o tehnică care funcționează prin întârzierea execuției unei funcții până când a trecut o perioadă de întârziere. Funcția de debounce detectează de fiecare dată când utilizatorul scrie și previne apelul către handler de căutare până când întârzierea a trecut. Dacă utilizatorul continuă să tasteze în perioada de întârziere, cronometrul este resetat și React apelează din nou funcția pentru noua întârziere. Acest proces continuă până când utilizatorul întrerupe tastarea.

  7 software puternic de proiectare PCB pentru a proiecta electronice

Așteptând ca utilizatorii să întrerupă tastarea, eliminarea se asigură că aplicația dvs. face doar cererile de căutare necesare, reducând astfel încărcarea serverului.

Cum să eliminați căutarea în React

Există mai multe biblioteci pe care le puteți folosi pentru a implementa debounce. De asemenea, puteți alege să îl implementați singur de la zero folosind funcțiile JavaScript setTimeout și clearTimeout.

Acest articol folosește funcția de debounce din biblioteca lodash.

Presupunând că aveți un proiect React gata, creați o nouă componentă numită Căutare. Dacă nu aveți un proiect funcțional, creați o aplicație React folosind utilitarul de creare a aplicației React.

În fișierul componentă Căutare, copiați următorul cod pentru a crea o casetă de introducere a căutării care apelează o funcție de gestionare la fiecare apăsare a tastei.

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

Pentru a elimina funcția handleSearch, transmiteți-o funcției de debounce din 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..."
    />
  );
}

În funcția de debounce, treceți funcția pe care doriți să o întârzieți, adică funcția handleSearch, și timpul de întârziere în milisecunde, adică 500ms.

Deși codul de mai sus ar trebui să întârzie apelul la cererea handleSearch până când utilizatorul întrerupe tastarea, nu funcționează în React. Vom explica de ce în secțiunea următoare.

  Cum să redimensionezi o imagine la un tapet de pe desktop

Debouncing și redări

Această aplicație folosește o intrare controlată. Aceasta înseamnă că valoarea de stare controlează valoarea intrării; de fiecare dată când un utilizator introduce în câmpul de căutare React actualizează starea.

În React, atunci când o valoare de stare se schimbă, React redă componenta și execută toate funcțiile din interiorul acesteia.

În componenta de căutare de mai sus, când componenta este redată din nou, React execută funcția de debounce. Funcția creează un nou cronometru care ține evidența întârzierii, iar cronometrul vechi rămâne în memorie. Când timpul acestuia se scurge, declanșează funcția de căutare. Aceasta înseamnă că funcția de căutare nu este niciodată anulată, este întârziată cu 500 ms. Acest ciclu se repetă la fiecare randare — funcția creează un nou cronometru, vechiul cronometru expiră și apoi apelează funcția de căutare

Pentru ca funcția de debounce să funcționeze, trebuie să o apelați o singură dată. Puteți face acest lucru apelând funcția de debounce în afara componentei sau utilizând tehnica de memorare. În acest fel, chiar dacă componenta se redă, React nu o va executa din nou.

Definirea funcției de debounce în afara componentei de căutare

Mutați funcția de debounce în afara componentei Căutare, așa cum se arată mai jos:

 import debounce from "lodash.debounce"

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

const debouncedSearch = debounce(handleSearch, 500);

Acum, în componenta Căutare, apelați debouncedSearch și introduceți termenul de căutare.

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

Funcția de căutare va fi apelată numai după expirarea perioadei de întârziere.

  15 Cea mai bună periuță de dinți Sonicare pentru dinți mai curați și mai albi

Memorarea funcției de debounce

Memorarea se referă la memorarea în cache a rezultatelor unei funcții și reutilizarea lor atunci când apelați funcția cu aceleași argumente.

Pentru a memoriza funcția de debounce, utilizați cârligul 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..."
    />
  );
}

Rețineți că ați împachetat și funcția handleSearch într-un cârlig useCallback pentru a vă asigura că React o apelează o singură dată. Fără cârligul useCallback, React ar executa funcția handleSearch cu fiecare re-rendare care face ca dependențele hook-ului useMemo să fie schimbate, care la rândul său ar apela funcția de debounce.

Acum, React va apela funcția de debounce numai dacă funcția handleSearch sau timpul de întârziere se schimbă.

Optimizați căutarea cu Debounce

Uneori, încetinirea poate fi mai bună pentru performanță. Atunci când gestionați sarcini de căutare, în special cu apeluri costisitoare de baze de date sau API, utilizarea unei funcții de debounce este calea de urmat. Această funcție introduce o întârziere înainte de trimiterea cererilor de backend.

Ajută la reducerea numărului de solicitări adresate serverului, deoarece trimite cererea doar după ce întârzierea a trecut și utilizatorul a întrerupt tastarea. În acest fel, serverul nu este supraîncărcat cu prea multe solicitări, iar performanța rămâne eficientă.