프론트엔드/JS

디바운스,쓰로틀

journey-dev 2024. 6. 12. 22:51

회사에서 순수js로 디바운스를 구현해야 하는 일이 생겼다.

프로젝트 내에 lodash를 여기저기 쓰고있어서 나는 디바운스 로직을 직접 구현하지 않고 편하게 쓰고있었다.

 

막상 직접 로직을 구현하려하니 많이 버벅였다.

라이브러리를 쓰기 전에 그 로직의 원리를 이해해야 하는데 라이브러리에 너무 기대고 있었던걸까

 

다시 기본을 다지도록


✅ 디바운스

1.개념 

: 여러번 발생하는 이벤트에서, 가장 마지막 이벤트 만을 실행되도록 제한함

 

2. 사용

: 사용자가 검색어를 입력할 때, 입력이 멈추면 서버에 요청을 보낼 때

: 버튼 연타시 불필요한 api호출을 막기 위해

 

3. 효과

: 불필요한 이벤트 핸들러의 실행을 줄일 수 있음

 

4. 내가 구현한 코드

- 버튼 클릭시 setTimeout함수가 반환한 Id를 Clear해서  setTimeout 로직 실행을 막는다.

- 제일 마지막 클릭시에만 setTimeout의 콜백함수 실행이 이뤄진다.

    const numberEl = document.querySelector(".countNum");
    const buttonEl = document.querySelector(".plus");

    // 디바운스 함수
    const debounce = (callbackFn, delay) => {
      let timerId; // 클로저

      return () => {
        if (timerId) {
          clearTimeout(timerId);
        }

        timerId = setTimeout(onClick, 500);
      };
    };

   // 클릭이벤트 함수
    const onClick = () => {
      const currentNum = +numberEl.innerText;
      numberEl.innerText = currentNum + 1;
    };

    buttonEl.addEventListener("click", debounce(onClick, 500));

 

5. 모범 코드

https://www.freecodecamp.org/korean/news/debounce-dibaunseu-javascripteseo-hamsureul-jiyeonsikineun-bangbeob-js-es6-yeje/

      const numberEl = document.querySelector(".countNum");
      const buttonEl = document.querySelector(".plus");

      function debounce(callbackFn, delay) {
        let timerId;
        return (...args) => {
          clearTimeout(timerId);
          timerId = setTimeout(() => {
            callbackFn.apply(this, args);
          }, delay);
        };
      }
      function onClick() {
        const currentNum = +numberEl.innerText;
        numberEl.innerText = currentNum + 1;
      }
      buttonEl.addEventListener("click", debounce(onClick, 500));

 

 

 스로틀

1. 개념

: 여러번 발생하는 이벤트를 일정 시간 동안, 한번만 실행 되도록 제한한다.

 

2. 사용 

: 스크롤 이벤트, 마우스 이동 이벤트, 리사이즈와 같이 빈번하게 발생하는 이벤트를 처리할 때 유용 

 

3. 효과

: throttle을 사용하면 이벤트 핸들러가 너무 자주 실행되는 것을 방지하고, 성능 이슈를 줄일 수 있다.

 

4. 내가 구현한 코드

- 첫 클릭에만 setTimeout의 콜백함수가 실행되고, 0.5초 동안은 함수 실행이 무시된다.

- 이후 0.5초 뒤 첫 클릭시 다시 콜백함수가 실행된다.

      const numberEl = document.querySelector(".countNum");
      const buttonEl = document.querySelector(".plus");

      // 쓰로틀
      const throttle = (callbackFn, delay) => {
        let isWaiting = false;

        return () => {
          if (!isWaiting) {
            setTimeout(() => {
              callbackFn();
              isWaiting = false;
            }, delay);
          }

          isWaiting = true;
        };
      };

      // 클릭이벤트
      const onClick = () => {
        const currentNum = +numberEl.innerText;
        numberEl.innerHTML = currentNum + 1;
      };

      buttonEl.addEventListener("click", throttle(onClick, 1000));

 

 


https://pks2974.medium.com/throttle-%EC%99%80-debounce-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC%ED%95%98%EA%B8%B0-2335a9c426ff