javascript

Debouncing, Throttling

hjcode 2020. 2. 26. 16:44

디바운싱과 쓰로틀링은 웹페이지의 성능을 향상시키기 위해 이벤트를 제한하는 방법입니다.
loadash나 underscore에는 이미 있는 기능입니다.

사용자가 키보드 입력을 중지할 때까지 ajax를 발생시키지 않는다거나
페이지의 스크롤을 측정할 때 주로 사용됩니다.
사용자가 길게 스크롤을 한다면 엄청나게 많은 이벤트가 발생하게 됩니다.
그 많은 이벤트를 수행하는 일이 큰 리소스를 잡아먹게 되고 성능에 문제가 발생합니다.

쓰로틀링

스크롤 이벤트가 빈번하게 발생할 때 쓰로틀링을 걸어줍니다.
몇 초, 몇 밀리초에 한번씩만 실행되게 제한을 걸어줍니다.

 

var timer;

window.addEventListener('scroll', e => {

  console.log('no throttling')
  
  if(!timer) {
  	timer = setTimeout(() => {
    	timer = null;
        console.log('throttling')
    }, 200)
  }

})

콘솔을 보시면 타이머를 걸어두어 200밀리초 후에 스스로 해제를 하고
스크롤 이벤트에 대한 요청을 보냅니다.

디바운스

디바운스는 특정시간이 지난 후 하나의 이벤트만 발생하게 하는 방법입니다.
예로 검색어를 입력하는데 엔터없이 ajax 요청이 실행된다면 글자 하나하나를
칠때마다 ajax요청이 실행됩니다. '펭수'를 입력한다면 'ㅍ','페','펭','ㅅ','수' 가 
모두 요청됩니다.

이와같은 상황은 유료 API를 사용한다면 큰 문제가 됩니다.
쿼리 하나하나가 다 비용이기 때문에 큰 손해가 생기게 되므로
디바운싱은 비용적인 문제와도 관련이 있습니다.

 

var timer;

document.querySelector('#input').addEventListener('input', function(e) {
  if (timer) {
    clearTimeout(timer);
  }
  timer = setTimeout(function() {
    console.log('ajax 요청', e.target.value);
  }, 200);
});

타자를 칠 때(input 이벤트 발생)마다 타이머를 설정합니다.

200ms동안 입력이 없으면 입력이 끝난 것으로 칩니다.

200ms 이전에 타자 입력이 발생하면 이전 타이머는 취소하고 새로운 타이머를 다시 설정하는 겁니다.

 

디바운싱과 스로틀의 가장 큰 차이점은 스로틀은 X밀리 초마다 정기적으로 기능 실행을 보장한다는 것입니다.
디바운스는 아무리 많은 이벤트가 발생해도 모두 무시하고 특정 시간사이에 어떤 이벤트도 발생하지 않았을 때 
딱 한번만 마지막 이벤트를 발생시키는 기법입니다.
따라서 5ms 가 지나기전에 계속 이벤트가 발생할 경우 콜백에 반응하는 이벤트는 발생하지 않고 계속 무시됩니다.

jsfiddle에서 보기

https://jsfiddle.net/hyuckjin/o2hf71mq/

References

https://www.zerocho.com/category/JavaScript/post/59a8e9cb15ac0000182794fa

반응형