[TIL 210624] 쓰로틀링(Throttling)과 디바운싱(Debouncing) 구현하기

Ko Seoyoung·2021년 6월 23일
0

✅ Today I Learned

목록 보기
1/16
post-thumbnail

쓰로틀링과 디바운싱이란?

쓰로틀링(Throttling)디바운싱(debouncing)은 사용자의 오버클럭(over clock)이 디바이스에 무리를 주는 것을 방지하기 위해 고의로 성능을 낮추는 조절 방식을 말한다.

얘네는 특히 검색 기능에서 쓰이면 유용하다. 우리가 '쓰로틀링'을 검색하는 상황에서 위 두 기법을 사용하지 않으면 요청은 다음과 같이 발생한다. 'ㅆ','쓰','쓰ㄹ','쓰로','쓰로ㅌ','쓰로트'... 이렇게 사용자가 매번 한글자씩 글자를 누를 때마다 api를 호출해서 큰 부하를 일으킬 수도 있다.

그렇다면 쓰로틀링과 디바운싱을 사용해 이러한 문제를 어떻게 해결할 수 있는지 살펴보자!

쓰로틀링

쓰로틀링은 발생되는 이벤트 중간에 Delay를 포함시킨다. Delay를 0.3초라고 한다면, 0.3초 이내에 연속적으로 발생된 이벤트에 대해서는 무시하는 것이다. 즉, '쓰로틀링'을 다음과 같은 속도로 10초동안 작성한다면 'ㅆ'(0.1초),'쓰'(0.16초),'쓰ㄹ'(0.24초),✅ '쓰로'(0.33초),'쓰로ㅌ'(0.4초),'쓰로트'(0.5초),✅ '쓰로틀'(0.63초)...가 될것이고 요청은 매번 보내는 것이 아니라 0.3초 마다 한번씩 (✅표시때 만) 보낸다. 쉽게말해서, 특정 주기마다 요청을 보내는 것!

  • 애니메이션을 구현하는 코드에서 많이 확인할 수 있음
  • 필터링(Filtering)의 방법 사용

디바운싱

그렇다면 디바운싱은 이를 어떻게 처리할까? 디바운싱은 이벤트 핸들러가 주기적으로 발생한 여러개의 이벤트를 하나로 묶어서 처리하는 방식이다. 이 때도 delay를 0.3초로 정한다면, 사용자가 자판을 계~~속 두드리다가 0.3초동안 아무 입력도 하지 않으면 요청이 보내진다.

  • 그루핑(Grouping)의 방법 사용

구현

핔에서는 장바구니에서 수량을 변경할 때 디바운싱을 적용했다.

코드

 // debounce
  const updateMyCartItem = useMemo(() => {
    let timer: NodeJS.Timeout;

    return (
      options: MutationHookOptions<
        UpdateMyCartItemData,
        UpdateMyCartItemVariables
      >
    ) => {
      setCount(options.variables.updateCartItemInput.quantity);
      clearTimeout(timer);
      // 0.3초 이전에 연속 클릭을 하면 사용자에게 보여지는 state만 변경된다.
      timer = setTimeout(() => {
        mutate(options);
        // 누르고 0.3초 지났을 때야 mutate로 api를 호출해 실제 값을 변경한다. 
      }, 300);
    };
  }, []);
  • 리액트에서 구현시 부딪힌 스코프&클로저 문제

처음엔 debouce를 모듈로 구현했다. 하지만 timer를 전역변수가 아닌 스코프가 있는 함수에 넣었더니 함수가 rerender될 때마다 다시 호출되어 누른만큼 여러 개의 타이머가 생성되었고, deboucing이 제대로 작동하지 않았다. 따라서 위와 같이 직접 호출되는 곳에 deboucing 코드를 직접 넣어주었다.


Refs

https://jins-dev.tistory.com/entry/웹프론트엔드에서-쓰로틀링Throttling과-디바운싱Debouncing의-개념

profile
Web Frontend Developer 👩🏻‍💻 #React #Nextjs #ApolloClient

0개의 댓글