Как да подобрите ефективността на търсенето в React с Debouncing

В React, когато внедрява функцията за търсене, манипулаторът onChange извиква функцията за търсене всеки път, когато потребителят въвежда в полето за въвеждане. Този подход може да причини проблеми с производителността, особено ако правите API извиквания или правите заявки към базата данни. Честите извиквания на функцията за търсене може да претоварят уеб сървъра, което да доведе до сривове или неотзивчив потребителски интерфейс. Debouncing решава този проблем.

Какво е Debouncing?

Обикновено вие прилагате функцията за търсене в React, като извиквате функция за манипулиране onChange при всяко натискане на клавиш, както е показано по-долу:

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

Въпреки че това работи, извикването към бекенда за актуализиране на резултатите от търсенето при всяко натискане на клавиш може да бъде скъпо. Например, ако търсите „webdev“, приложението ще изпрати заявка до бекенда със стойностите „w“, „we“, „web“ и т.н.

Debouncing е техника, която работи чрез забавяне на изпълнението на функция до изтичане на период на забавяне. Функцията за отблъскване разпознава всеки път, когато потребителят въвежда, и предотвратява извикването на манипулатора за търсене, докато не изтече закъснението. Ако потребителят продължи да въвежда в рамките на периода на забавяне, таймерът се нулира и React извиква отново функцията за новото забавяне. Този процес продължава, докато потребителят спре да пише.

  Обяснени честоти и настройки на еквалайзера на музикални плейъри

Като изчаква потребителите да спрат въвеждането на пауза, премахването на отскок гарантира, че вашето приложение прави само необходимите заявки за търсене, като по този начин намалява натоварването на сървъра.

Как да дебоунсирате търсенето в React

Има няколко библиотеки, които можете да използвате за прилагане на debounce. Можете също да изберете да го внедрите сами от нулата, като използвате функциите setTimeout и clearTimeout на JavaScript.

Тази статия използва функцията debounce от библиотеката lodash.

Ако приемем, че имате готов проект на React, създайте нов компонент, наречен Search. Ако нямате работещ проект, създайте React приложение с помощта на помощната програма за създаване на React приложение.

Във файла на компонента за търсене копирайте следния код, за да създадете поле за въвеждане на търсене, което извиква манипулираща функция при всяко натискане на клавиш.

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

За да деактивирате функцията handleSearch, предайте я на функцията debounce от 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..."
    />
  );
}

Във функцията debounce предавате функцията, която искате да забавите, т.е. функцията handleSearch, и времето на забавяне в милисекунди, т.е. 500ms.

  Как да поправите замръзнал Mac

Въпреки че горният код трябва да забави извикването на заявката handleSearch, докато потребителят спре да въвежда, той не работи в React. Ще обясним защо в следващия раздел.

Отстраняване на отскок и повторно изобразяване

Това приложение използва контролиран вход. Това означава, че стойността на състоянието контролира стойността на входа; всеки път, когато потребител въведе в полето за търсене, React актуализира състоянието.

В React, когато стойността на състоянието се промени, React рендерира повторно компонента и изпълнява всички функции вътре в него.

В горния компонент за търсене, когато компонентът се изобрази повторно, React изпълнява функцията за премахване на отскок. Функцията създава нов таймер, който следи закъснението, а старият таймер остава в паметта. Когато времето му изтече, той задейства функцията за търсене. Това означава, че функцията за търсене никога не се отклонява, тя се забавя с 500 ms. Този цикъл се повтаря при всяко изобразяване – функцията създава нов таймер, старият таймер изтича и след това извиква функцията за търсене

За да работи функцията debounce, трябва да я извикате само веднъж. Можете да направите това, като извикате функцията debounce извън компонента или като използвате техниката за запаметяване. По този начин, дори ако компонентът се рендерира повторно, React няма да го изпълни отново.

Дефиниране на функцията Debounce извън компонента за търсене

Преместете функцията за отблъскване извън компонента за търсене, както е показано по-долу:

 import debounce from "lodash.debounce"

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

const debouncedSearch = debounce(handleSearch, 500);

Сега, в компонента за търсене, извикайте debouncedSearch и подайте думата за търсене.

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

Функцията за търсене ще бъде извикана само след изтичане на периода на забавяне.

  Вземете рекламен сървър за вашия уебсайт, като използвате тези 9 платформи

Запомняне на функцията Debounce

Мемоизирането се отнася до кеширане на резултатите от функция и повторното им използване, когато извиквате функцията със същите аргументи.

За да запаметите функцията debounce, използвайте куката 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..."
    />
  );
}

Обърнете внимание, че също сте обвили функцията handleSearch в кука useCallback, за да сте сигурни, че React я извиква само веднъж. Без куката useCallback, React ще изпълни функцията handleSearch с всяко повторно изобразяване, правейки зависимостите от промяната на куката useMemo, което на свой ред ще извика функцията debounce.

Сега React ще извика функцията debounce само ако се промени функцията handleSearch или времето за забавяне.

Оптимизирайте търсенето с Debounce

Понякога забавянето може да бъде по-добро за ефективността. Когато се справяте със задачи за търсене, особено със скъпи извиквания на база данни или API, използването на функция за премахване на отскок е правилният начин. Тази функция въвежда забавяне преди изпращане на задните заявки.

Той помага да се намали броят на заявките, отправени към сървъра, тъй като изпраща заявката само след изтичане на забавянето и потребителят е поставил на пауза въвеждането. По този начин сървърът не се претоварва с твърде много заявки и производителността остава ефективна.