2023. 7. 4. 13:16ㆍzerobase/react
수많은 정보들을 로드하기 위해서 브라우저는 무한 로딩에 빠질 수가 있다.
한번에 많은 양의 데이터들을 로드해야하니 속도는 당연히 느려질 수 밖에 없을 것이다.
이러한 방법을 해결하기 위해서 데이터를 분할하여 보여주는 방법이 있다. 크게 2가지가 있는데, 페이지네이션과 무한스크롤이라고 하는 방법이 있다.
페이지네이션은 페이지를 번호로 분할해서 넘기면서 볼 수 있는 방법이고
무한스크롤은 스크롤을 내리면서 무한으로 정보가 나오는 방법이다.
오늘은 무한스크롤에 대해서 알아보려고 한다.
무한스크롤의 장점과 단점
장점
- 컨텐츠 탐색이 쉬워짐
- 사용자 참여가 쉬워짐
- 다음 콘텐츠를 보기 위한 추가 클릭이 필요없고 페이지 로드 시간이 짧음
- 모바일일 때 더 유용하게 적용됨
- 화면이 작을수록 스크롤이 길어지기 때문에 모바일 환경에서 콘텐츠를 보여주기 직관적이고 사용하기 쉬움
단점
- 페이지 성능이 느려임
- 검색 및 원래 위치로 돌아오기 힘듦
- 스크롤 막대가 데이터의 양을 반영하지 못함
- 푸터를 찾기 어려움
무한스크롤 구현 방법
scroll event
import renderList from './renderList';
const app = document.querySelector('#app');
const fetchMoreTrigger = document.querySelector('#fetchMore');
let page = 0;
const fetchMore = async () => {
const target = page ? fetchMoreTrigger : app;
target.classList.add('loading');
await renderList(page++);
target.classList.remove('loading');
};
const onScroll = e => {
const {
scrollHeight,
scrollTop,
clientHeight,
} = e.target.scrollingElement;
if (scrollTop + clientHeight === scrollHeight) {
fetchMore()
}
};
document.addEventListener('scroll', onScroll);
fetchMore();
1. addEventListner로 scroll 이벤트를 받고, onScroll 함수를 실행시킴
2. 함수는 e를 인자로 받고, 구조분해할당으로 scrollHeight, scrollTop, clientHeight를 선언하고 할당받음
3. scrollTop + clientHeight === scrollHeight 조건문은 스크롤바 수직 위치 + 유저가 보고 있는 창의 높이를 더한것이 현재 scrollHeight와 같은지 판별하는 조건문임
4. 참이라면 fetchMore()을 통해 데이터들을 더 불러옴
5. fetchMore()은 async await로 데이터를 비동기 처리로 불러오게 됨
하지만 이 방법은 스크롤 단위 1마다 이벤트리스너가 실행되어 규모가 큰 프로젝트에서 스크롤 할 양이 많아진다면, 선응이 저하 될 수 있음
이를 보완하기 위해 throttle과 debounce가 있음
throttle
이벤트에 의한 콜백을 일정시간 뒤에 호출하는 기법
var throttler;
window.onscroll = () => {
// throttle
if(!throttler) {
throttler = setTimeout(() => {
throttler = null;
console.log('throttle');
}, 200);
}
}
0.2초마다 throttle이 콘솔에 출력됨
debounce
연이어 호출되는 콜백 중 마지막 혹은 처음 것만 호출하도록 하는 기법
const debounce = (event, delay) => {
let timeoutId = null;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(event.bind(null, ...arg), delay);
};
// 코드 생략 ...
document.addEventListener('scroll', debounce(onScroll, 500));
fetchMore();