Skip to content

☄️트러블 슈팅 : 검색기능에서 과도한 API 통신으로 인한 성능 저하

Hyeji Han edited this page Jan 30, 2023 · 1 revision

문제

검색기능을 구현할 때, input값이 변화할 때마다 검색 API 통신을 하는 것이 아닌 검색어를 모두 입력할 때 검색 API 통신을 하고 싶다.

문제 상황

검색을 하기 위해서 검색하고 싶은 단어만 API 통신을 하면 되는데 input에 값이 변화할 때마다 onChange로 검색을 하게 된다면 계속 검색을 하게되어 API요청시 비용과 손해가 생기게 되고 성능도 저하된다.

예시로 "Hello"를 검색한다면 "H" -> "He" -> "Hel" -> "Hell" -> "Hello" 이런 식으로 5번이나 요청이 되거나 함수가 실행될 것이다. 하지만 우리가 원래는 결과는 "Hello"의 검색결과 이기에 결국 "Hello"라고 모두 입력시에만 검색이 되면 된다.

문제의 원인

검색어를 입력하는 태그인 inputonChange를 할때마다 API 통신을 하였다. 그렇게 된다면 값이 변화할 때마다 통신을 하게 되어 비용과 손해가 생기며 성능 또한 저하된다. 바뀔 때마다가 아닌 온전히 값이 모두 입력되었다고 판단될 때 통신을 하도록 해야한다.

원인 해결을 위한 방법 고민

키보드의 값을 누를 때마다 keydown일 때, 그 다음 keydown이 들어오는 시간 타이머를 체크한 후 타이머가 정해진 시간보다 적다면 통신을 안하도록 설정하고 싶었다. 이러한 방식을 debouncing이라고 한다.

Dedounce - 디바운스

디바운스는 연이어 같은 함수가 호출된다면 호출되는 함수들 중 마지막 함수만 호출하는 것을 말한다. 디바운스를 설정하게 되면 setTimeout으로 1초라고 설정하고 1초 안에 같은 함수가 호출이 안된다면 검색 기능이 실행된다.

Hello로 예를 들자면 H를 입력한 후 1초안에 e를 입력하면 다시 타이머가 1초로 재설정된다. 이런 식으로 Hello가 모두 입력되고 o 다음에 1초동안 어떤 문자도 입력이 안된다면 검색 함수가 실행된다. 결과적으로 Hello를 모두 입력해야 한번의 검색이 실행되는 것이다.

해결 방법 도입 및 결과

재사용성을 위하여 useDebounce라는 커스텀 훅을 만든 후에 사용하였다. 아래 코드는 useDebounce.js 코드 예시이다.

import { useEffect, useState } from 'react';

const useDebounce = (value, delay) => {
  const [debouncedValue, setDebouncedValue] = useState(value);
  
  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(timer);
    }; //value 변경 시점에 clearTimeout을 해줘야함.
  }, [value]);

  return debouncedValue;
};

export default useDebounce;

input값을 받아온 후에 커스텀 훅을 활용하여 500ms 시간안에 다른 문자가 입력되지 않는다면 검색 API 통신을 하도록 하였다.

const debouncedSearchText = useDebounce(checkchange, 500); //500ms안에 다른 문자가 입력되지 않으면 검색어가 변경되도록함.

결과적으로 API 통신이 여러번 했었는 디바운싱을 적용한 후 한번만 통신을 하게 되어 성능이 향상되었다.

관련 블로그 글 : 블로그 링크