728x90
Throttling & debouncing
1. 짧은 시간 간격으로 연속해서 이벤트가 발생했을 때 과도한 이벤트 핸들러 호출을 방지하는 기법
2. setTimeout 메서드를 사용해서 Throttling & debouncing을 구현
=> Throttling: 이벤트는 일어나지만 함수는 한 번만 호출되는 것(오락실 광클)
=> debouncing: 짧은 시간 간격으로 연속해서 이벤트가 발생하면
이벤트 헨들러를 호출하지 않다가 마지막 이벤트로부터 일정시간(delay)가 경과한 후에 한 번만 호출하도록 하는 것
=> 메모리 누수: Throttling & debouncing이 실행될 때 페이지 이동이 이루어졌음에도 불구하고
Throttling & debouncing이 실행되는 것
=> Lodash: 리렌더링 됐을 때도 Throttling & debouncing이 실행될 수 있도록 하는 방법
Throttling & debouncing 코드
// throttling
const throttle = (delay) => {
if (timerId) {
// timerId가 있으면 바로 함수 종료
return;
}
console.log(`API 요청 실행 ${delay}ms 시간만큼 추가 요청은 안받습니니다`);
timerId = setTimeout(() => {
console.log(`${delay}ms 만큼 지남 --> 추가요청 받음`);
timerId = null;
}, delay);
};
// ---------------------------------------------------------------------
// debouncing
const debounce = (delay) => {
// timerId가 null이 아니면 clearTimeout을 통해 null로 만듦
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(() => {
console.log(`마지막 요청으로부터 ${delay}ms 지났으므로 API 요청 실행`);
timerId = null;
}, delay);
};
메모리 누수를 방지하는 방법
// useEffect를 사용해서 리렌더링시 timerId값 null로 초기화
useEffect(() => {
return () => {
// 언마운트시 특정 동작 가능
if (timerId) {
clearTimeout(timerId);
}
};
}, []);
Lodash
// 직접만든 debounce
const debounce = (callback, delay) => {
let timerId = null;
return (...args) => {
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(() => {
callback(...args);
}, [delay]);
};
};
// useCallback을 써서 메모이제이션을 해야함
const handleSearchText = useCallback(
// lodash를 import하면 _.debounce를 사용할 수 있음
debounce((text) => {
setSearchText(text);
}, 2000),
[]
);
728x90
'[항해99] TIL' 카테고리의 다른 글
5주차 WIL (React Hook) (0) | 2023.09.10 |
---|---|
24일차 (인증/인가) (0) | 2023.09.10 |
22일차 (react-query) (0) | 2023.09.08 |
21일차(thunk, custom-hocks) (0) | 2023.09.06 |
20일차(Ul 태그로 Select 구현) (0) | 2023.09.06 |