디바운싱과 쓰로틀링

김종현·2024년 5월 2일
0

구현 기능

목록 보기
2/2

디바운스(Debounce)

이벤트를 그룹화하여 연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것.

-사용자가 키보드 입력을 중지할 때 까지 웹에서 ajax 검색 이벤트를 발생시키지 않고 싶을 때 사용한다.
-사용자가 창 크기 조정을 멈출 때까지 기다렸다가 resizing event를 반영하고 싶을 때와 같은 경우에 사용한다.

const $input = document.querySelector("#input");
const $app = document.querySelector("#app");

const callAjaxRequest = (e) =>{
  $app.insertAdjacentHTML("beforeend", `<p>ajax 요청 : ${e.target.value}</p>`);
};

const debounce = (func) => {let timer;
  
  return(e)=>{if(timer){
      clearTimeout(timer);
    }
    
   timer = setTimeout(func(e), 500);
  };
};

$input.addEventListener("input", debounce(callAjaxRequest));

① 클로저를 이용, 함수 내부에 timer 선언
② timer가 있을 경우 타이머를 초기화, 타이머를 재설정.

-디바운스는 이벤트를 처리하는 시점에 따라 다음 두 종류가 있다.

Trailing Edge

-가장 마지막에 실행하는 함수를 처리하고 그 전의 이벤트들을 무시.

Leading Edge

-처음 실행하는 함수를 처리하고 그 뒤의 이벤트들을 무시.

-쓰로틀링과 굉장히 유사하게 작동하는데 첫 요청 이후 일정시간 모든 요청을 무시한다는 점에서 유사점을 가지나 다음과 같은 차이가 있다.
Leading Edge : 스크롤 조작과 같은 동작이 끝나고 특정 시간이 지나 이벤트가 하나 발생
Throttling : 이벤트가 하나 발생한 뒤 특정 시간동안 이벤트 발생을 막고 그 후에 요청을 허용

const debounce = (func, wait, leading = true) =>{let timer;
  return (e) => {let callNow = leading && !timer
    
③   const later = () =>{
      timer = null;
      if(!leading) {
        func(e)
      }
    };clearTimeout(timer);
    timer = setTimeout(later, wait);if(callNow){
      func(e)
    }
  };
};

★leading 값이 true일 경우 leading edge, false일 경우 trailing edge로 실행
① 클로저를 이용, 함수 내부에 timer 선언
② timer의 값이 변하기 전에 callNow 값을 저장. 실행 시 callNow === true
③ leading이 false인 경우 실행되는 함수. setTimeout의 콜백으로 호출되어 이벤트 요청이 더 없을 경우 timer를 초기화.
④ setTimeout을 초기화하고 timer값을 설정
⑤ leading이 true고 timer가 없으면 이벤트 함수 실행

실행 흐름
callNow === true 할당 ②
=> timer가 없으므로 celarTimeout이 무시되고 timer가 설정됨 ④
=> callNow가 true이므로 이벤트 함수 실행 ⑤
=> timer 변수가 할당되었으므로 callNow === false 할당 ②
=> 돌아가는 timer 초기화 후 재설정 ④, callNow === false이기 때문에 이벤트 함수 실행하지 않음 ⑤

이와 같이 설정된 시간 동안의 이벤트 요청을 지속적으로 무시, 마지막 이벤트 실행 후 설정된 시간 동안 아무 이벤트도 들어오지 않는다면 setTimeout의 콜백 함수가 호출되어 timer가 null로 초기화되어 callNow가 true가 되도록 함.

쓰로틀(Throttle)

마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것

-주로 성능개선을 위해 사용되며(무한 스크롤) 이벤트를 일정 주기마다 발생하도록 하는 기술이다.

const $app = document.querySelector("#app");
const $countNumber = document.querySelector("#count-number");

let count = 0;

const throttle = (func) =>{let timer;
  
  return() =>{if(!timer){
      timer = setTimeout( ()=>{
        timer = null;
        func();
      }, 1000);
    }
  };
};

const increaseCountNumber = () =>{
  $countNumber.innerText = count++;
};

$app.addEventListener("scroll", throttle(increaseCountNumber)); 

① 클로저를 이용, 함수 내부에 timer 선언
② timer가 없을 시에만 특정 시간(1000ms)이 지난 후에 timer를 초기화하고 지정해놓은 이벤트 함수 실행.

스크롤 이벤트가 발생할 때 마다 1000ms를 계속 갱신하며 이벤트를 막고 스크롤이 멈추면 timer를 초기화하고 이벤트를 실행한다.

참조 영상 : https://www.youtube.com/watch?v=By49qqkzmzA

profile
고양이 릴스 매니아

0개의 댓글