반응형
이벤트 제어하는 기법
Throttle과 Debounce는 이벤트가 과도한 횟수로 발생하여 이벤트 핸들러가 무거운 연산을 수 없이 많이 수행하는 경우에 제약을 걸어 제어할 수 있는 수준으로 이벤트를 발생시키는 것을 목표로 하는 기술이다.
디바운싱
연속으로 호출되는 같은 함수들 중에 마지막에 호출되는 함수만 실행되도록 하는 것
혹은 제일 처음만 호출되게 하는 것
실제 사례
문제 상황
- React-query의 useMutation을 사용해 서버에 데이터를 등록하는 작업 중에서 해당 등록하는 버튼을 빠르게 클릭하면 동일한 요청이 클릭한 만큼 실행되었다.
- 해당 함수가 성공을 하면 다른 페이지로 라우팅을 해주는 작업이었는데 해당 작업이 완료되기전에 빠르게 클릭하면 서버도 로딩 중인 걸 판단하지 못하고 서버에 클릭한 만큼 요청이 들어갔다.
해결법
type Props = {
timer: NodeJS.Timer | undefined;
setTimer: React.Dispatch<React.SetStateAction<NodeJS.Timer | undefined>>;
fn: () => Promise<void>;
delay: number;
};
export const debouncePromise = ({ timer, setTimer, fn, delay }: Props) => {
if (timer) {
clearTimeout(timer);
}
setTimer(setTimeout(fn, delay));
};
출처 : 재민쿤
매개변수 설명
- timer : useState로 작업할 함수를 담음
- timer를 변경하는 함수
- 실행할 서버 연동 함수
- 딜레이 시간
흐름
- timer가 있든 없든 timer에 계속해서 실행할 함수를 넣어줌
- timer가 있다면 원래 있던 timer을 취소함
- 이 함수를 취소하는 작업이 중요함
- setTimeout은 해당 딜레이 시간 이후에 함수를 실행하는 것이기에 빠르게 클릭한 함수 호출은 모두 무시되고 마지막 작업만 실행이 되는 것이다.
쓰로틀링
⭐ 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않는 것
- 주로 스크롤 이벤트에서 많이 사용한다고 함
- 특정한 시간 주기로 실행된다
let timer;
document.querySelector('#input').addEventListener('input', function (e) {
// 타이머가 없을 때만 타이머 설정.
// 만약 200ms가 지나서 해당 함수를 실행하면 타이머는 사라진다. (timer = null)
// 만약 타이머 설정 후 200ms가 지나지 않았다면 아무 일도 일어나지 않는다.
// 따라서 최소 200ms 마다 한번씩만 아래의 코드가 실행된다.
if (!timer) {
timer = setTimeout(function() {
timer = null;
console.log(`api 요청 : ${e.target.value}`);
}, 200);
}
});
lodash
- lodash에서 제공하는 함수들
디바운스 : https://lodash.com/docs/4.17.15#debounce
쓰로틀 : https://lodash.com/docs/4.17.15#throttle
느낀 점
1. 팀원에 도움으로 디바운싱으로 쉽게 해결할 수 있단 걸 알고 역시 집단지성의 힘은 위대하다란 걸 다시금 깨달았다.
2. 해당 개념들(디바운싱, 쓰로틀링)에 대해 있는지 조차 인지를 하지 못했기에 해당 에러를 어떻게 해결할지 막막했는데 역시 인지를 하는 것이 가장 중요한 것 같다 그래서 개발 관련 글을 더 많이 읽어야겠다고 다짐했다.
3. 또 한 걸음 성장할 수 있었던 에러였다.
ref
반응형
'Frontend' 카테고리의 다른 글
Next.js app router API Routes를 활용한 주문형 재검증 (0) | 2024.08.01 |
---|---|
styled-component로 GlobalStyle 정의하기 (0) | 2023.04.04 |
Next.js 쓰면 SSR 하고 있는거 아님? (2) | 2022.11.18 |
프론트엔드 면접 경험 (0) | 2022.11.16 |
[JS] this란? (0) | 2022.08.23 |