Како побољшати перформансе претраге у реаговању са одбијањем

У Реацт-у, када имплементира функцију претраживања, онЦханге руковалац позива функцију претраге сваки пут када корисник унесе у поље за унос. Овај приступ може изазвати проблеме са перформансама, посебно ако упућујете АПИ позиве или постављате упите бази података. Чести позиви функцији претраге могу преоптеретити веб сервер, што може довести до кварова или корисничког интерфејса који не реагује. Одбијање решава овај проблем.

Шта је дебоунцинг?

Обично имплементирате функцију претраживања у Реацт-у тако што ћете позвати функцију руковања онЦханге при сваком притиску на тастер као што је приказано у наставку:

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

Док ово функционише, позив бацкенд-у за ажурирање резултата претраге при сваком притиску тастера може бити скуп. На пример, ако сте тражили „вебдев“, апликација би послала захтев бацкенд-у са вредностима „в“, „ве“, „веб“ и тако даље.

Одбијање је техника која функционише тако што одлаже извршење функције док не прође период кашњења. Функција дебоунце детектује сваки пут када корисник куца и спречава позив руковаоцу претраге док кашњење не истекне. Ако корисник настави да куца у периоду одлагања, тајмер се ресетује и Реацт поново позива функцију за ново одлагање. Овај процес се наставља све док корисник не заустави куцање.

Чекањем да корисници паузирају куцање, одбијање осигурава да ваша апликација прави само неопходне захтеве за претрагу и на тај начин смањује оптерећење сервера.

Како да одбијете претрагу у Реацт-у

Постоји неколико библиотека које можете користити за имплементацију дебоунце. Такође можете изабрати да га сами имплементирате од нуле користећи ЈаваСцрипт функције сетТимеоут и цлеарТимеоут.

Овај чланак користи функцију дебоунце из лодасх библиотеке.

Под претпоставком да имате спреман Реацт пројекат, креирајте нову компоненту под називом Претрага. Ако немате радни пројекат, креирајте Реацт апликацију користећи услужни програм за креирање Реацт апликације.

У датотеци компоненте Сеарцх копирајте следећи код да бисте креирали поље за унос за претрагу које позива функцију руковаоца при сваком притиску тастера.

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

Да бисте одбили функцију хандлеСеарцх, проследите је функцији за уклањање одбијања са лодасх-а.

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

У функцији дебоунце, преносите функцију коју желите да одложите, тј. функцију хандлеСеарцх, и време кашњења у милисекундама, тј. 500 мс.

Иако би горњи код требало да одложи позив захтева хандлеСеарцх док корисник не паузира куцање, он не ради у Реацт-у. Објаснићемо зашто у следећем одељку.

Дебоунцинг и Рендерс

Ова апликација користи контролисани унос. То значи да вредност стања контролише вредност улаза; сваки пут када корисник унесе у поље за претрагу Реацт ажурира стање.

У Реацт-у, када се вредност стања промени, Реацт поново приказује компоненту и извршава све функције унутар ње.

У горњој компоненти претраге, када се компонента поново рендерује, Реацт извршава функцију дебоунце. Функција креира нови тајмер који прати кашњење, а стари тајмер седи у меморији. Када време истекне, покреће функцију претраге. То значи да се функција претраживања никада не поништава, већ касни 500 мс. Овај циклус се понавља на сваком рендеру— функција креира нови тајмер, стари тајмер истиче и онда позива функцију претраге

Да би функција дебоунце функционисала, морате је позвати само једном. То можете да урадите тако што ћете позвати функцију дебоунце ван компоненте или користећи технику меморисања. На овај начин, чак и ако се компонента поново прикаже, Реацт је неће поново извршити.

Дефинисање функције дебоунце изван компоненте претраге

Померите функцију дебоунце изван компоненте Сеарцх као што је приказано у наставку:

 import debounce from "lodash.debounce"

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

const debouncedSearch = debounce(handleSearch, 500);

Сада, у компоненти Претрага, позовите дебоунцедСеарцх и унесите термин за претрагу.

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

Функција претраге ће бити позвана тек након истека периода одлагања.

Меморирање функције Дебоунце

Мемоизинг се односи на кеширање резултата функције и њихово поновно коришћење када позовете функцију са истим аргументима.

Да бисте меморисали функцију одбијања, користите усеМемо куку.

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

Имајте на уму да сте такође умотали функцију хандлеСеарцх у усеЦаллбацк куку како бисте осигурали да је Реацт позове само једном. Без усеЦаллбацк куке, Реацт би извршио функцију хандлеСеарцх са сваким поновним рендеровањем правећи зависност промене куке усеМемо која би заузврат позвала функцију дебоунце.

Сада ће Реацт позвати функцију дебоунце само ако се промени функција хандлеСеарцх или време кашњења.

Оптимизујте претрагу помоћу Дебоунце

Понекад успоравање може бити боље за перформансе. Када се бавите задацима претраге, посебно са скупим позивима базе података или АПИ-ја, најбоље је користити функцију дебоунце. Ова функција уводи одлагање пре слања позадинских захтева.

Помаже у смањењу броја захтева упућених серверу, јер шаље захтев тек након што прође кашњење и корисник паузира куцање. На овај начин, сервер се не преоптерећује са превише захтева, а перформансе остају ефикасне.