JavaScript

디바운싱과 쓰로틀링

ea_jung 2023. 7. 14. 16:55

 

💡 이번주 데브 코스 강의에서 디바운싱과 스로틀링에 대한 내용이 나와서 한번 다시 정리해 보려 합니다! 

"debouncing"이라는 영어 표현이 익숙하지 않아서 한번 찾아봤더니 적절한 한국어 표현이 없더라고요! 전등의 스위치를 누르는 상황을 가정해 봤을 때 신호가 한 번만 가서 바로 전등의 불이 켜진다고 생각하지만 실제로는 신호의 안정성이 확립되기까지 시간이 걸린다고 하네요. 이 시간 동안 스위치 내의 접점에서 여러 번의 접촉과 분리가 일어날 수 있는데, 이로 인해 노이즈가 발생하고 여러 번의 상태 변화가 일어날 수 있다고 해요. 우리가 원하는 건 스위치를 켜서 보내는 신호 한 번인데 중간에 불필요한 신호가 가면 안 되겠죠? 이를 해결하기 위해 도입된 방법이  "debouncing"이라고 해요. 앞에서 예시로 들었던 스위치를 누르는 상황을 클릭 이벤트로 생각하면 이해가 되실 겁니다!  일정시간 내에 똑같은 event가 발생하는 경우 앞에서 들어오는 event를 취소하면서 event를 지연시키고 가장 마지막에 들어오는 event를 실행시키는걸 "debouncing" 이라고 합니다!

"throttling"에서 throttle쓰로틀은 기계나 엔진에서 연료 또는 공기의 유입을 제어해 속도를 제한하는 기술을 의미해요. 이 용어는 기계의 스로틀 (즉 가속기, 목을 조른다 조절한다는 뜻도 있어요.)와 관련이 있으며, 엔진 출력을 조절하여 속도를 제한하는 동작을 가리켜요. 
소프트웨어에서의 쓰로틀링은 이러한 기계적인 개념을 차용하여, 일정 시간 내 가장 처음 들어온 event만 실행시키고 나머지 event를 무시합니다. 리소스 사용이나 데이터 처리 속도 등을 제어하여 시스템의 동작을 제한하거나 조절하는 기술이라고 할 수 있어요. 주로 네트워크 트래픽, 데이터베이스 쿼리, API 요청 등에서 사용되며, 과도한 리소스 사용을 방지하고 시스템의 안정성과 효율성을 유지하는 데 도움을 준다고 하네요?!

예시 코드를 보며 이해해 봅시다!

 

디바운씽

인터넷 쇼핑 중 장바구니에 넣을 상품을 클릭하거나 온라인 결제를 하는 상황에서 실수로 여러 번 클릭하는 일이 생기면 곤욕스럽겠죠? 이를 방지하기 위해 디바운씽을 사용합니다. 또 다른 예시로는 검색 기능의 키 이벤트가 있는데 검색 버튼을 누르지 않아도 사용자가 입력한 값이 실시간으로 인식되어 자동으로 검색 요청이 보내진다면 네트워크에 너무 큰 부하가 걸릴 수 있습니다. 이럴 경우 일정 시간이 지난 후 검색 요청이 1번만 보내지도록 디바운싱을 이용할 수 있습니다. 

 

input에서의 key event를 이용해서 설명해 볼게요!

 

const inputElement = document.querySelector('#ID값');
const DELAY = 2000;
const handleChange = () => {
  console.log('요청!');
}

let timer;

inputElement.addEventListener('input', () => {
  if (timer) { clearTimeout(timer) };
  timer = setTimeout(handleChange, DELAY);
});

 

이벤트가 발생하면 timer 변수에 setTimeout 함수가 값으로 할당됩니다. 

2초 시간이 지나기 전에 또 이벤트가 발생하게 되면 timer가 초기화되고 다시 2초로 설정되기 때문에 콜백함수인 handleChange() 함수의 실행이 계속 지연되게 됩니다!

결국 2초 동안 event 일어나지 않았을 때 비로소 handleChange() 함수가 실행됩니다. 

 

참고로 setTimeout() 에는 id 값이 할당됩니다. 

 

쓰로틀링

쓰로틀링을 적용하면 좋은 예시로는 scroll, resize, drag, mouse 이벤트, 애니메이션 등이 있어요.

예를 들어 스크롤 이벤트의 경우, 크롬 기준 2px 단위로 이벤트가 발생하게 되는데 사용자가 1초에 1000px의 스크롤을 하게 되는 경우에는 약 500번의 이벤트가 발생되므로 성능에 좋지 않습니다.

이러한 경우에 time = 100 간격으로 이벤트가 실행되도록 쓰로틀링을 적용하면 실행 횟수를 최대 10번으로 줄일 수 있습니다. (스크롤를 1초 동안 연속으로 계속 한다면 스크롤이 처음 시작할때 한번만 event handler가 작동하겠죠?)

 

const DELAY = 100;
const handleScroll = () => {
  timer = null;
  console.log('스크롤!');
}
        
let timer;  
   
window.addEventListener('scroll', () => {
  if (!timer) { timer = setTimeout(handleScroll, DELAY) };
});

 

이벤트가 발생했을 때, timer 변수의 값이 비어있다면 setTimeout 함수를 값으로 할당합니다. 

그리고 콜백 함수 handleScroll() 내에서 timer를 null으로 초기화해줍니다. 

 

처음 스크롤을 하면 timer에 값이 할당되어 있지 않기 때문에 if문이 실행되고 timer에 id 값이 할당되고 그리고 다시 handleScroll 함수에 의해 timer에 null 이 할당되고 처음 콘솔이 실행되게 됩니다. DELAY 시간 내에 아무리 스크롤을 많이 한다고 해도 처음에 실행됐던 콘솔 한 번만 실행되게 됩니다. 그리고 DELAY 시간이 지나면 다시 handleScroll 함수작동 됩니다!

 

정리하자면 디바운싱은 여러 번의 중복 event가 일어날 수 있는 상황에서 이를 단일 이벤트로 처리하기 위해서 일정 시간 내에 가장 마지막에 일어난 event만을 감지하는 방법입니다. 이를 통해 정확한 입력을 인식하고 처리할 수 있게 됩니다. 쓰로트링은 일정시간 내 가장 처음 들어온 event만 실행시키고 나머지 event를 무시해 과도한 리소스 사용을 막는 데 사용되는 겁니다!
반응형