debounce & throttle

IT공부중·2020년 10월 14일
3

JavsScript

목록 보기
12/22
post-thumbnail

이벤트 핸들러가 많은 연산(예 : 무거운 계산 및 기타 DOM 조작)을 수행(이벤트 핸들러의 과도한 횟수가 발생하는 것)하는 경우 에 대해 제약을 걸어 제어할 수 있는 수준으로 이벤트를 발생(그 핸들러를 더 적게 실행하면 빠져 나갈 수 있음)시키는 것을 목표로 하는 기법

사용 예시

  • 사용자가 창 크기 조정을 멈출 때까지 기다렸다가 resizing event 사용하기 위해

  • 사용자가 키보드 입력을 중지(예: 검색창) 할 때까지 ajax 이벤트를
    발생시키지 않기 위해

  • 페이지의 스크롤 위치를 측정하고 최대 50ms 마다 응답하기를 바랄 경우

  • 앱에서 요소를 드래그 할 때 좋은 성능을 보장하기 위해

설명과 코드

debounce랑 throttle 코드 예시를 작성해봤다. 최대한 관심사의 분리를 하여 모든 함수들에 적용할 수 있게 코드를 짜보았다.

해당 함수는 클로저를 활용하였고 함수를 반환하여 일반 함수와 비슷하게 사용할 수 있다.

debounce

한꺼번에 일어나는 한 종류의 여러 개의 이벤트가 마지막 하나의 이벤트만 발생하도록 하는 기법

throttle

이벤트를 일정한 주기마다 발생하도록 하는 기법

전체 예시 코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id='normal' type='text'/>
    <input id='debounce' type='text'/>
    <input id='throttle' type='text'/>

    <script>
        const debounce = (func, time = 500) => {
          let timer = null;
          return (...parameters) => {
            if (timer) {
              clearTimeout(timer);
            }
            timer = setTimeout(() => {
              func(...parameters);
              timer = null;
            }, time);
          };
        };
        
        const throttle = (func, time = 500) => {
          let timer = null;
          return (...parameters) => {
            if (!timer) {
              timer = setTimeout(() => {
                func(...parameters);
                timer = null;
              }, time);
            }
          };
        };
        const conoleLogValue = (e) => console.log(e.target.value);
        const debounceChangeHandler = debounce(conoleLogValue);
        const throttleChangeHandler = throttle(conoleLogValue);
        document.querySelector('#normal').addEventListener('keydown', conoleLogValue);
        document.querySelector('#debounce').addEventListener('keydown', debounceChangeHandler);
        document.querySelector('#throttle').addEventListener('keydown', throttleChangeHandler);
        
        
        </script>
</body>
</html>

결과

아무것도 적용하지 않은 input은 칠 때마다 모든 글자가 쳐지는 것을 볼 수 있다.

debounce를 적용한 input은 연속적으로 쳤을 때 다 치고 끝난 다음에 console.log가 찍히는 것을 볼 수 있다.

throttle을 적용한 input은 완전 연속적으로는 아니지만 일정 간격을 두고 함수가 실행되는 것을 볼 수 있다.

사용 기준

마지막 것만 요청을 보내야 하면 debounce
첫번째 것을 보내고 일정 시간 동안 안 보내려면 throttle

참고

https://www.zerocho.com/category/JavaScript/post/59a8e9cb15ac0000182794fa 제로초 블로그
https://webclub.tistory.com/607

예전에 공부했던 기억...

profile
4년차 프론트엔드 개발자 문건우입니다.

0개의 댓글