디바운스로 불필요한 네트워크 요청 줄이기

taeyooooon·2023년 5월 13일
0
post-thumbnail

아래 사진처럼 검색 키워드가 변경될 때 마다 불필요하게 네트워크 요청을 계속 보내는 모습입니다.
개인 프로젝트 수준에서는 무시해도 될 수준이지만 실제 현업에서는 이런 불필요한 요청들이 모이면 비용 문제가 은근 클거 같아서
이번 기회에 개념만 알고있던 디바운스를 이용해서 최적화를 해보았습니다.

...
const Component = () => {
  const [keyword, setKeyword] = useState('');
  const {
    data: users,
    isLoading,
    error,
  } = useSWR<User[]>(`/api/search/${keyword}`);
  ...
}

1. Debounce와 Throttle이란?

디바운스쓰로틀은 특정 함수의 실행이 반복적으로 실행될 때 네트워크 또는 Cpu등의 과부화를 막기위한 프로그래밍 기법입니다.
다수의 호출로 인한 성능저하를 방지하기 위해 호출 수 자체를 줄이면 됩니다.

Debounce는 다수의 호출을 묶는 것이다.
100번의 요청이 단기간에 몰릴 경우 마지막 요청만을 실행한다고 생각하면 되고,

Throttle은 다수의 호출에 간격을 두는 것 이다.
PC에 관심이 있는 사람이라면 쓰로틀링에 대해 많이 알고있을텐데 똑같은 개념입니다.
CPU의 발열이 심해지면 기기 보호를 위해 CPU 클럭수를 급격히 낮추는 것을 의미합니다.

아래 링크에서 디바운싱과 쓰로틀링을 직접 체험해보면 바로 이해가 갈 개념입니다

https://redd.one/blog/debounce-vs-throttle

2. Debounce 예시 코드

인자로 받은 value를 디바운싱한 뒤 리턴해주는 커스텀 훅

// @/hooks/useDebounce.ts
import { useState, useEffect } from 'react';

const useDebounce = (value: string, delay: number = 500) => {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(handler);
  }, [value, delay]);

  return debounced;
};

export default useDebounce;

이제 디바운싱 한 검색 키워드를 SWR 인자로 전달한다.

const Component = () => {
  const [keyword, setKeyword] = useState('');
  const debouncedKeyword = useDebounce(keyword);
  const {
    data: users,
    isLoading,
    error,
  } = useSWR<User[]>(`/api/search/${debouncedKeyword}`);
  ...
}

keyword가 변경되면서 리랜더링이 발생할 때 useSWR가 다시 호출되어야 할 것 같다고 생각할 수도 있는데,
해당 부분은 SWR이 알아서 내부적으로 캐싱 된 값을 사용하기 때문에 중복 네트워크 요청을 하지 않습니다!

3. 정리

Debounce는 다수의 호출을 묶고 끝날 때까지 기다렸다가 시작되고, Throttle은 다수의 호출의 일정 간격으로 계속 실행한다는 점이 다르다.
따라서 확실한 최적화를 위해서는 Debounce로 함수를 한 번만 실행되도록 하는 것이 효과적일 것 같지만,
유저가 즉각적인 결과를 기대하는 기능에 있어서는 Throttle을 사용하여 UX를 신경쓰는 것도 좋은 방법같다.

참고한 링크

https://github.com/vercel/swr/issues/110

profile
응애🐣 프론트엔드

0개의 댓글