회사에서 순수js로 디바운스를 구현해야 하는 일이 생겼다.
프로젝트 내에 lodash를 여기저기 쓰고있어서 나는 디바운스 로직을 직접 구현하지 않고 편하게 쓰고있었다.
막상 직접 로직을 구현하려하니 많이 버벅였다.
라이브러리를 쓰기 전에 그 로직의 원리를 이해해야 하는데 라이브러리에 너무 기대고 있었던걸까
다시 기본을 다지도록
✅ 디바운스
1.개념
: 여러번 발생하는 이벤트에서, 가장 마지막 이벤트 만을 실행되도록 제한함
2. 사용
: 사용자가 검색어를 입력할 때, 입력이 멈추면 서버에 요청을 보낼 때
: 버튼 연타시 불필요한 api호출을 막기 위해
3. 효과
: 불필요한 이벤트 핸들러의 실행을 줄일 수 있음
4. 내가 구현한 코드
- 버튼 클릭시 setTimeout함수가 반환한 Id를 Clear해서 setTimeout 로직 실행을 막는다.
- 제일 마지막 클릭시에만 setTimeout의 콜백함수 실행이 이뤄진다.
const numberEl = document.querySelector(".countNum");
const buttonEl = document.querySelector(".plus");
// 디바운스 함수
const debounce = (callbackFn, delay) => {
let timerId; // 클로저
return () => {
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(onClick, 500);
};
};
// 클릭이벤트 함수
const onClick = () => {
const currentNum = +numberEl.innerText;
numberEl.innerText = currentNum + 1;
};
buttonEl.addEventListener("click", debounce(onClick, 500));
5. 모범 코드
const numberEl = document.querySelector(".countNum");
const buttonEl = document.querySelector(".plus");
function debounce(callbackFn, delay) {
let timerId;
return (...args) => {
clearTimeout(timerId);
timerId = setTimeout(() => {
callbackFn.apply(this, args);
}, delay);
};
}
function onClick() {
const currentNum = +numberEl.innerText;
numberEl.innerText = currentNum + 1;
}
buttonEl.addEventListener("click", debounce(onClick, 500));
✅ 스로틀
1. 개념
: 여러번 발생하는 이벤트를 일정 시간 동안, 한번만 실행 되도록 제한한다.
2. 사용
: 스크롤 이벤트, 마우스 이동 이벤트, 리사이즈와 같이 빈번하게 발생하는 이벤트를 처리할 때 유용
3. 효과
: throttle을 사용하면 이벤트 핸들러가 너무 자주 실행되는 것을 방지하고, 성능 이슈를 줄일 수 있다.
4. 내가 구현한 코드
- 첫 클릭에만 setTimeout의 콜백함수가 실행되고, 0.5초 동안은 함수 실행이 무시된다.
- 이후 0.5초 뒤 첫 클릭시 다시 콜백함수가 실행된다.
const numberEl = document.querySelector(".countNum");
const buttonEl = document.querySelector(".plus");
// 쓰로틀
const throttle = (callbackFn, delay) => {
let isWaiting = false;
return () => {
if (!isWaiting) {
setTimeout(() => {
callbackFn();
isWaiting = false;
}, delay);
}
isWaiting = true;
};
};
// 클릭이벤트
const onClick = () => {
const currentNum = +numberEl.innerText;
numberEl.innerHTML = currentNum + 1;
};
buttonEl.addEventListener("click", throttle(onClick, 1000));
'프론트엔드 > JS' 카테고리의 다른 글
동기 VS 비동기, Promise와 async/await (0) | 2024.11.24 |
---|---|
문자열 정렬시 sort가 아닌 localeCompare메서드 사용 (0) | 2024.08.10 |
URLSearchParams (0) | 2023.10.31 |
spread문법 , rest파라미터 , arguments의 차이 (0) | 2023.07.25 |
parseInt, parseFloat, Math.floor 에 대해 (0) | 2023.07.22 |