이벤트를 효율적으로 다루기 위한 debouce를 알아보자.

디바운스?

디바운스는 실행되는 이벤트들 중 마지막 이벤트만 실행한다.

mousemove, scroll 등, 이벤트가 발생될 때 과도한 이벤트의 발생을 막기 위해 디바운스스로틀을 이용하여 이벤트 발생을 제어한다.

예를 들어,

// 이렇게 코드를 짜고 마우스를 움직이면 아주 조그마한 움직임에도 수십번의 'hi'가 찍히는 것을 콘솔창에서 확인할 수 있다.
document.addEventListener('mousemove', () => console.log('hi'));

이런 과도한 이벤트의 발생은 브라우저의 성능을 저하시킨다.

또 다른 예로,

이 코드는 사용자가 값을 입력할 때 마다 콘솔창에 인풋값을 보여준다.

  <body>
    <input type="text" class="input" />
  </body>
  <script>
    input.addEventListener('input', ({ target }) => console.log(target.value));
  </script>

/* 결과
 * input: 'h'  return: 'h'
 * input: 'hi' return: 'hi'  <--- the result a developer wants
*/

이러한 경우에 사용자가 입력을 마친 이후의 값을 필요로 한다면,

마지막 이벤트를 제외한 나머지는 불필요한 이벤트의 발생이다.

Debounce를 이용하여 이벤트를 제어해보자.

// 1초 이내에 입력을 하면 console에 인풋값을 출력하지 않는다.
let timer;
input.addEventListener('input', ({target}) => {
  if (timer) {
    clearTimeout(timer);
  }
  timer = setTimeout(() => {
    console.log('입력:', target.value);
  }, 1000);
});
};

유틸함수로 debounce 사용하기

const main = () => {
  const input = document.querySelector('.input');
  const ms = 1000;

  const debounce = (fn, ms) => {
    let timer;
    return (e) => {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        fn(e);
      }, ms);
    };
  };
  const printInputValue = ({ target }) => console.log(target.value);

  const inputHandler = debounce((e) => printInputValue(e), ms);

  input.addEventListener('input', inputHandler);
};

main();

작동원리: input 이벤트가 발생 -> inputHandler -> debounce(콜백함수, ms)

debounce 내의 timer를 통해 printInputValue 함수를 제어한다.

현재는 단순히 input의 값을 제어하기 위한 debounce 함수를 만들었다.

더 나아가 fetch, promise와 조합해 범용성 있는 유틸을 만들어 볼 예정이다.




© 2021.01. by somedaycode

Powered by theorydb