[Javascript] Throttle과 Debounce
Throttle
장애물을 사용하여 유체의 흐름 속도를 늦추는 뜻으로, 프로그래밍에서는 특정속도로만 작업을 수행하는 것을 가리킨다. 여러 번 발생하는 이벤트를 일정시간 동안 한번만 실행한다.
Debounce
여러 번 발생하는 이벤트에서 지정된 시간 내의 가장 마지막 입력만 실행한다.
Throttle 사용사례와 코드 예시
지속적으로 업데이트 되는 다른 상태와 안정적으로 동기화할 때 사용한다.
ex) 계속 화면 밑바닥과 얼마나 떨어져 있는 지 확인해야 하는 scroll이벤트의 경우, 짧은 시간 내에 너무 많은 이벤트를 받으면 Jank* 가 일어날 수도 있지만, Throttle로 이벤트 실행 주기를 조절할 수 있다.
Jank : 일반적으로 메인스레드에서 너무 긴 작업을 하거나, 렌더링을 차단하거나, 백그라운드에서 프로세서 기능을 많이 소모해서 일어나는 사용자 인터페이스의 부진
mousemove 이벤트가 실행되는 동안 일정 시간마다 출력하는 예시
function throttle(callback, limit = 500) { // (1)
let wait = false;
return function (...args) { // 익명 함수
if (!wait) {
callback.apply(this, args); // 콜백 실행
wait = true;
setTimeout(() => (wait = false), limit); // 제한 시간이 지난 후 다시 활성화
}
};
}
ground.addEventListener("mousemove", throttle(handle, 1000)); // (2)
function handle(e) {
console.log(e); //이벤트 객체 e를 받아 콘솔에 출력
} // (3)
- throttle 함수는 callback과 limit을 입력으로 받아 스로틀링된 함수를 반환한다.
- wait 플래그를 사용해 제한 시간 동안 추가 호출을 차단한다.
- callback.apply(this, args)는 호출 시 컨텍스트와 인자를 유지한다.
- 코드 추가 설명
실행 흐름:
- throttle(handle, 1000) 실행:
- handle이라는 콜백 함수와 limit 값(1000ms)을 인자로 전달한다.
- 이 함수는 내부에서 wait 상태와 로직을 포함한 익명 함수를 반환한다.
- 익명 함수가 이벤트 리스너로 등록됨:
- 반환된 익명 함수가 mousemove 이벤트 리스너로 등록된다.
- 이제 마우스를 움직일 때마다 반환된 익명 함수가 호출된다.
- 이벤트 발생 시 익명 함수 실행:
- mousemove 이벤트가 발생하면 반환된 익명 함수가 호출된다.
- 호출될 때, 이 익명 함수는 다음 과정을 실행한다.
익명 함수의 실행 흐름:
이벤트 발생:- mousemove 이벤트가 발생하면 이 익명 함수가 실행된다.
- 이 함수는 ...args를 통해 이벤트 객체(또는 추가 인자)를 받는다.
- wait 상태 체크:
- if (!wait) 조건문에서 wait 값이 false인지 확인한다.
- wait이 false인 경우에만 콜백 함수가 실행된다.
- 콜백 실행:
- callback.apply(this, args)를 통해 handle 함수가 호출된다.
- 여기서 callback은 throttle 호출 시 전달된 handle 함수다.
- this는 호출 컨텍스트를 유지하며, 이벤트 객체는 args로 전달된다.
- callback.apply(this, args)를 통해 handle 함수가 호출된다.
- 잠금 활성화:
- wait = true로 설정되어, 다음 이벤트가 들어와도 일정 시간 동안은 실행되지 않는다.
- 타이머 설정:
- setTimeout(() => (wait = false), limit)이 실행된다.
- 이 타이머는 limit(1초) 이후에 wait 값을 false로 변경한다. 이를 통해 다음 이벤트를 처리할 준비를 한다.
실행 결과
Debounce 사용사례와 코드 예시
사용자 입력에 응답할 때, 사용자가 입력을 일시중지 하면 이벤트를 처리하도록 한다.
ex) 비밀번호 입력 중, 비밀번호가 짧다는 경고는 사용자가 입력을 일시중지 했을 때 출력된다.
resize 이벤트를 사용자가 멈췄을 때 실행하는 예시
window.addEventListener(
"resize",
debounce(handle, 500)
);
function debounce(callback, limit = 500) {
let timeout;
return function (e) {
clearTimeout(timeout);
timeout = setTimeout(() => {
callback.call(this, e);
}, limit);
};
}
function handle(e) {
console.log(e);
}
- debounce 함수는 callback과 limit(지연 시간)을 입력으로 받아 디바운싱된 함수를 반한다.
- 이벤트가 연속적으로 발생하면 clearTimeout을 통해 기존의 타이머를 제거하고, 마지막 이벤트 이후에만 콜백 함수가 실행된다.
- callback.call(this, e)는 함수 실행 시 컨텍스트(this)와 인자를 유지한다.
실행 결과
요약
Throttle | Debounce | |
콜백 실행 시점 | 이벤트가 연속적으로 발생하더라도 일정 간격마다 실행 | 마지막 이벤트 이후 일정 시간 지연 시 실행 |
주요 목적 | 이벤트 실행 주기 조절을 통해 성능 최적화 | 이벤트를 마지막 1번만 실행하도록 제한 |
대표적인 사용 사례 | - 스크롤 이벤트 - 마우스 이동 - 터치 드래그 이벤트 |
- 검색창 자동완성 - 브라우저 리사이즈 - 입력 폼 검증 |
장점 | - 이벤트를 주기적으로 처리하여 실시간 반응성 유지 | - 짧은 시간에 반복 실행 방지로 네트워크, CPU 리소스 절약 |
https://css-tricks.com/debouncing-throttling-explained-examples/
Debouncing And Throttling Explained Through Examples | CSS-Tricks
The following is a guest post by David Corbacho, a front end engineer in London. We've broached this topic before, but this time, David is going to drive the
css-tricks.com
https://developer.mozilla.org/en-US/docs/Glossary/Debounce
Debounce - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
Debouncing, in the context of programming, means to "batch" all operations requested during a specific interval into a single invocation.
developer.mozilla.org
https://developer.mozilla.org/en-US/docs/Glossary/Throttle
Throttle - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
Throttling originally meant slowing down the rate of fluid flow using an obstruction. In the context of programming, it refers to slowing down a process such that an operation can only be performed at a certain rate.
developer.mozilla.org