debounce vs throttle
2020/03/08 15:34
항상 헷갈려서 정리해 본다.
#TIL#throttle#debounce

개발을 하다보면 자주 안쓰다보니 혹은 너무 당연하게 생각하다 가끔 헷갈리거나 쌩둥맞게 낯설게 다가오는 것들이 있다. debouncethrottle도 얼마 전에 뭐가 뭐였지 하고 다시 찾아봤던 것 중 하나다. 다시 보지 않기 위해 기록한다던 누군가(베토벤이었나?)의 말을 빌려 다신 헷갈리지 않기 위해 정리를 해본다.

일단 둘다 실행을 제어하기 위해, 좀 더 정확히는 빈번한 실행을 방지하기 위한 목적으로 사용한다.

Debounce

마지막 호출 이후 특정 시간이 지나야 호출 되도독 제한한다. 다른 말로는 이벤트를 그룹화 한다고도 한다. 즉 연속으로 발생하는 이벤트를 하나의 그룹으로 그룹화해서 한 번만 호출이 발생하도록 제한 것이다.

debounce

debounce를 활용하기 좋은 예제는 자동 완성이다. 사용자가 타이핑을 계속하는데 매번 api를 호출해서 결과를 받아서 그리면 그 사이에 다른 타이핑이 발생하고 결국 보여주기도 전에 새로운 결과가 필요한 상황이 발생하는 비효율이 발생할 수 있다. 따라서 타이핑이 더이상 발생하지 않아 타이핑이 완료됐다는 판단이 들면 요청을 발생시키는 것이다.

debounce에서는 두 가지 선택이 있다. 그룹화 된 호출들의 처음에 호출할지 대기 시간이 지난 후에 호출 할지이다. 즉 이벤트1이 발생하자마자 이벤트1을 실행하고 대기시간이 지난 후의 이벤트2가 발생했을 때 다시 이벤트2를 즉시 실행하거나, 이벤트1이 발생하고 대기시간이 지난 후에 이벤트1을 실행하고 대기시간이 지나고 이벤트2가 발생하면 다시 대기시간이 지난 후에 이벤트2를 실행한다. 차이라고 한다면 즉시 실행을 하게 되면 호출이 빈번하지 않은 경우 debounce가 적용되지 않은 것과 동일한 시점에 이벤트가 발생 한다는 것이다.

leading

Throttle

일정 주기마다 한 번씩만 호출 되도록 제한한다. debounce와 차이점은 특정 시간 안에 최소 한 번의 실행을 보장한 다는 것이다. 다르게 표현하자면 이벤트가 발생한 후 특정 시간 동안 발생하는 이벤트들을 무시하고 정해진 시간이 지난 후에 다시 이벤트를 발생 시키는 것이다.

throttle의 예로는 무한 스크롤을 수 있다. 다음 내용을 미리 가져오기 위해 끝에 도달했는지를 검사해야 하는데 이를 스크롤이 발생할 때 마다 하는건 매우 비효율 적이다. 실제 이벤트 발생보다 덜 빈번하게 주기를 낮춰서 검사하는 것이 좋은데 이때 사용할 수 있다.

requestAnimationFrame(rAF)

throttle과 동일한 효과를 내는 브라우저 native API이다. 매 프레임 마다 실행 되는데 기본적으로 16ms(60fps)마다 실행이 된다. 차이가 있다면 무엇보다 requestAnimationFrame은 브라우저 API라는 점이다. 그렇기 때문에 사용이 편하고 브라우저가 렌더링 스케줄에 대한 최적화를 하기 때문에 렌더링에 있어서는 더 좋을 수 있다. 하지만 모든 브라우저에서 지원하지 않기 때문에 polyfill이 필요할 수 있고 node.js에서는 지원하지 않기 때문에 서버에서는 사용할 수 없다. 추가로 rAF는 다른 두 함수와 다르게 시작 시점을 직접 컨트롤해야 한다는 것이다.

그렇다면 언제 사용하는 것이 좋을까? rAF의 경우 위에서 언급했듯이 렌더링과 관련된 처리를 할 때 매우 유용하다. 브라우저 native API인데다 렌더링에 맞추어져 있기 때문이다. 대신 렌더링이 아닌 경우, 예를 들어 서버 API 호출이나 애니메이션 같은 렌더링의 시작이나 종료를 결정해야 하는 경우에는 debouncethrottle이 유용하다. 특히 16ms 보다 덜 빈번하게 주기를 조절해야 하는 경우에는 특히 사용해야 한다.

정리를 해보면,
debounce는 키입력과 같이 갑자기 이벤트가 몰리는 상황에서 그룹화를 통한 제어가 필요할 때,
throttle은 정해진 매 주기마다 이벤트 실행을 보장해야 할 때,
requestAnimationFrame은 throttle과 유사하지만 렌더링과 관련된 (화면에 무언가를 그린다거나 부드러운 애니메이션 효과 등) 작업을 처리할 때 사용하면 좋다.

좀 더 자세한 내용과 실제 예제를 확인하고 싶으면 아래 참고의 링크를 확인하면 된다.

참고

Debouncing and Throttling Explained Through Examples | CSS-Tricks