Debounce&Throttle 개념

huurray·2021년 5월 13일
1
post-thumbnail

들어가기

Debounce와 Throttle은 이벤트를 효율적으로 처리하기 위한 개발 기법이다. 양적으로 크게 반복되는 이벤트를 처리할 때 실제로 처리되는 이벤트의 빈도를 줄여서 성능 상의 유리함을 가져오기 위함이다.

Debounce

연이어 호출되는 함수들 중 마지막 함수만을 호출한다.

예전에 검색어 입력에 따라 자동으로 검색 결과를 보여줘야하는 기능을 넣었을때 Debounce의 개념을 적용한 적이 있다. 검색 키워드가 한자씩 입력될 때마다 API를 호출해서 데이터를 가져오게 되면 너무 많은 요청이 발생될 수 있다. 그래서 검색어가 입력되고 다른 입력이 200ms 시간 안에 없을 경우 API 호출하도록 변경하여서 성능을 높였다.

이렇게 이벤트를 그룹화하여 특정시간이 지난 후 하나의 이벤트만 발생하도록 하는 기법이 Debounce이다.

Javascript에서는 보통 연속적인 이벤트를 타이머 함수의 콜백으로 설정하고 제한 시간 내에 연속적인 이벤트가 발생하면 설정한 타이머 함수를 지워주는 방식으로 Debounce를 구현한다.

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

이렇게 이벤트를 처리하면 아래와 같이 연속적인 이벤트 중 마지막 이벤트만 처리할 수 있다.

키워드 자동 완성 기능, 리사이즈 기능과 같이 연속된 이벤트 중 마지막 이벤트만 처리해도 되는 경우의 기능들을 구현할 때 사용하면 성능상이 이점을 가져갈 수 있다.

Throttle

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

throttle은 이벤트를 일정한 주기마다 발생하도록 하는 기법이다. 설정시간으로 200ms를 주게되면 해당 이벤트는 200ms 동안 최대 한번만 발생하게 된다. 이벤트의 호출을 일정 시간을 기준으로 일정하게 실행되게 제한을 두는 것이기 때문에 성능적인 이점과 예측가능하다는 이점도 가져갈 수 있다.

Javasciprt에서는 역시 타이머 함수를 이용해 일정시간마다 이벤트를 발생하도록 처리한다. 그리고 일정 시간 내에는 이벤트가 발생하지 않도록 한다.

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

이렇게 하면 검색 키워드가 입력되면 그 순간부터 200ms 후에 반드시 API요청을 실행하고 그 사이에는 이벤트가 발생하건 발생하지 않건 실행 되지 않는다.

검색 키워드의 예시에서는 Debounce기법이 더 효율적으로 보인다. 보통 Throttle은 scroll 관련 이벤트를 핸들링할때 사용되는데, 트위터에서 스크롤 관련 버벅임이 발생했을 때 존 레식이 해결책으로써 제안한 방법론이라고도 한다.

마무리

DOM 이벤트를 기반으로 반복적으로 실행되는 과정중에는 최적화가 필요한 부분이 반드시 있다. 웹 최적화 기법 중 자주 사용할만한 Debounce와 Throttle을 공부해보니 자주 구현하는 기능들에 딱 필요한 기법들이어서 잘 활용할 수 있을 것 같다.

직접 구현하기도 하지만 lodash나 다른 오픈소스에 구현되어 있는 Debounce, Throttle 함수를 가져다가 쓰는 것도 좋은 방법이다.(하지만 lodash로 인해 무거워질 수 있겠지?)

다음번엔 requestAnimationFrame을 공부해 애니메이션이나 타이머를 구현하는 것에 대해 공부해보자.

참고

쓰로틀링과 디바운싱 - 제로초님 블로그
debouncing-throttling - css-tricks

profile
Frontend Developer.

0개의 댓글