무한스크롤을 구현했다.
그러나 스크롤을 내릴때 호출이 너무 많이 되는걸 발견했다..
스크롤 전
스크롤 후
데이터를 한번 더 불러오는데 몇번이 호출되는지. 이를 막는 방법이 필요했고, 쓰로틀링과 디바운싱이 떠올랐다.
디바운싱은 이벤트를 모두 모아 마지막 이벤트에서 특정 시간이 지난 후 하나의 이벤트를 발생시키고, 쓰로틀링은 주기마다 이벤트를 모아 한번만 발생시킨다. 여기서는 쓰로틀링이 좋겠다고 판단했다.
직접 구현해보는 방법도 있겠으나, 내가 아는 방법은 setTimeOut의 방식으로 작동하기에 callstack의 상황에 따라 원하는대로 작동하지 않을 수 있다고 들었다. 그래서 lodash를 사용하기로 했다.
나는 yarn과 typescript를 사용중이므로 아래와 같이 작성하여 설치했다.
install
yarn add @types/lodash
그 후 lodash를 import하고
import { throttle } from 'lodash';
기존 코드를 throttle 내부에 넣어준다.
기존 코드
const ref = useIntersect(async (entry, observer) => {
observer.unobserve(entry.target);
if (isNextPage && !isFetching) {
// 이전 offset에 size를 더하여 다음 페이지 데이터를 가져오도록 설정
setOffset((prevOffset) => prevOffset! + size);
refetch();
}
});
useEffect(() => {
if (data) {
setIsNextPage(data.isNextPage);
// 새로운 데이터를 현재 데이터 뒤에 추가
setList((prevList) => [...prevList, ...data.list]);
}
}, [data]);
throttle이 적용된 코드
const throttledLoadMore = throttle(() => {
if (isNextPage && !isFetching) {
// 이전 offset에 size를 더하여 다음 페이지 데이터를 가져오도록 설정
setOffset((prevOffset) => prevOffset! + size);
refetch();
}
}, 1000); // 1초에 한 번만 호출되도록 설정
const ref = useIntersect(async (entry, observer) => {
observer.unobserve(entry.target);
throttledLoadMore();
});
useEffect(() => {
if (data) {
setIsNextPage(data.isNextPage);
// 새로운 데이터를 현재 데이터 뒤에 추가
setAnimeList((prevList) => [...prevList, ...data.list]);
}
}, [data]);
결과
아직 많다고 생각이 들지만.. 기존과 비교하면 정말 적다. 근데 왜 호출이 두번이지..? 이건 나중에 확인해야겠다.
23. 08. 23 > lodash의 throttle을 사용할 때 time을 주게 되면 setTimeOut의 방식으로 작동한다는 소문을 들었다. 조금 더 찾아보고 수정이 필요하다면 수정해야겠다.
'기록 > TIL' 카테고리의 다른 글
2023.08.24 - e.stopPropagation (0) | 2023.08.24 |
---|---|
2023.08.23 - Jotai use 3신기 사용해보기 (0) | 2023.08.23 |
2023.08.21 - TypeScript url 파라미터로 request를 보내기 위해 배열로 받기, react does not recognize the `~~~` prop on a DOM element. (0) | 2023.08.21 |
2023.08.18 - jotai 기본적인 사용법 (0) | 2023.08.18 |
2023.08.17 - git에서 특정 브랜치만 clone하기 (0) | 2023.08.17 |