이벤트 핸들러가 많은 연산(예 : 무거운 계산 및 기타 DOM 조작)을 수행(이벤트 핸들러의 과도한 횟수가 발생하는 것)하는 경우 에 대해 제약을 걸어 제어할 수 있는 수준으로 이벤트를 발생(그 핸들러를 더 적게 실행하면 빠져 나갈 수 있음)시키는 것을 목표로 하는 기법
사용자가 창 크기 조정을 멈출 때까지 기다렸다가 resizing event 사용하기 위해
사용자가 키보드 입력을 중지(예: 검색창) 할 때까지 ajax 이벤트를
발생시키지 않기 위해
페이지의 스크롤 위치를 측정하고 최대 50ms 마다 응답하기를 바랄 경우
앱에서 요소를 드래그 할 때 좋은 성능을 보장하기 위해
debounce랑 throttle 코드 예시를 작성해봤다. 최대한 관심사의 분리를 하여 모든 함수들에 적용할 수 있게 코드를 짜보았다.
해당 함수는 클로저를 활용하였고 함수를 반환하여 일반 함수와 비슷하게 사용할 수 있다.
한꺼번에 일어나는 한 종류의 여러 개의 이벤트가 마지막 하나의 이벤트만 발생하도록 하는 기법
이벤트를 일정한 주기마다 발생하도록 하는 기법
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input id='normal' type='text'/>
<input id='debounce' type='text'/>
<input id='throttle' type='text'/>
<script>
const debounce = (func, time = 500) => {
let timer = null;
return (...parameters) => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func(...parameters);
timer = null;
}, time);
};
};
const throttle = (func, time = 500) => {
let timer = null;
return (...parameters) => {
if (!timer) {
timer = setTimeout(() => {
func(...parameters);
timer = null;
}, time);
}
};
};
const conoleLogValue = (e) => console.log(e.target.value);
const debounceChangeHandler = debounce(conoleLogValue);
const throttleChangeHandler = throttle(conoleLogValue);
document.querySelector('#normal').addEventListener('keydown', conoleLogValue);
document.querySelector('#debounce').addEventListener('keydown', debounceChangeHandler);
document.querySelector('#throttle').addEventListener('keydown', throttleChangeHandler);
</script>
</body>
</html>
아무것도 적용하지 않은 input은 칠 때마다 모든 글자가 쳐지는 것을 볼 수 있다.
debounce를 적용한 input은 연속적으로 쳤을 때 다 치고 끝난 다음에 console.log가 찍히는 것을 볼 수 있다.
throttle을 적용한 input은 완전 연속적으로는 아니지만 일정 간격을 두고 함수가 실행되는 것을 볼 수 있다.
마지막 것만 요청을 보내야 하면 debounce
첫번째 것을 보내고 일정 시간 동안 안 보내려면 throttle
https://www.zerocho.com/category/JavaScript/post/59a8e9cb15ac0000182794fa 제로초 블로그
https://webclub.tistory.com/607
예전에 공부했던 기억...