무한스크롤 자체는 쉽게 구현 가능하다.
0. hasNextPage:boolean, page:number (+pageSize:number and others)을 쿼리스트링으로 백엔드에 api요청을 보낸다.
1. 하단에 target div(div든 뭐든 아무거나)를 만든다. 해당 div가 observe되면 다음페이지 데이터를 fetch한다.
2. 현재까지 데이터 array에 새로 fetch한 데이터를 덧붙힌다.
하지만 성능면에서 고민할 사항들이 많이 생긴다. 애초에 많은 데이터를 다루기 때문에..
1. 어쩌다보면 불필요하게 target div가 빠른시간내에 자주 요청되고, 백엔드에 부하를 주는 요청을 할 수 있다.
디바운스와 쓰로틀로 해결한다.
서비스기획에 따라 적절한 것을 선택해야한다.
무한스크롤의 예를 생각해보자,
디바운스의 경우
target div가 매우 높은 빈도로 노출됐을 시 사용자가 스크롤을 일정시간동안 멈춘다면, 다음페이지를 1번만 불러올 것이다.
쓰로틀의 경우
target div가 매우 높은 빈도로 노출됐을 시 일정 주기로 요청을 끊어서 다음페이지를 x번 불러올 것이다.(ex 3초동안 200번 노출됐고 0.5ms마다 1번씩 불러오기로 한다면 6번)
2. 프리페칭
사용자가 스크롤을 끝까지 내려 target div가 노출된 순간이 아닌, target div가 노출되기 조금 전에 다음페이지 요청을 보낸다.
그럼 더 부드러운 무한스크롤이 가능할 것이다. target div를 잘 만들어 속이거나 intersection observer의 rootmargin을 조절하는걸 고려해볼 수 있다.
3. 이미지 최적화
보이는 이미지만 게으르게 로드한다. 이미지를 신경안쓰면 경험상 성능에 악영향을 쉽게준다.
가능하다면, 이미지를 가벼운 확장자(or 해상도)로 사용하고 리사이징을 줄이고 크기를 작게 표시할 수 있는지를 디자이너에게 문의해본다.
저해상도이미지를 우선불러오고 그 다음에 고화질이미지로 바꾸는 테크닉도 있겠다.
loading = "lazy" or nextjs의 Image컴포넌트 사용을 고려한다.
4. UI
어쩔 수 없이 성능이 느리다면, 최대한 유저의 경험을 악화시키지 않는것도 방법이다.
로딩 인디케이터, 스켈레톤ui가 있다.
5. 가상화
보이는 것에만 집중하는건 중요하다.
현재 scrollY와 보이는 리스트의 인덱스를 비교해 보이지 않은건 가상화한다.
역시 이건 react-window라는 인기많은 라이브러리로 사용하는 것 같다.
7. 캐싱
모든 리스트 컴포넌트를 새로운 페이지를 불러올때마다 리랜더링해야할까? 이는 브라우저의 구토를 유발할 수 있다.
대부분 이전에 있는 리스트 컴포넌트들은 브라우저가 일할 필요가 없다. 메모제이션을 고려한다.
React Memo가 대안이겠다.
'개발' 카테고리의 다른 글
vanilla extract 시작하기 (0) | 2024.03.21 |
---|---|
해외 웹사이트 번역 키고 이용할 시 가끔씩 오류가 나는 원인 추측 (0) | 2024.03.18 |
쌓임 맥락에 대해 주의할 점 (feat opacity) (0) | 2024.03.03 |
nextjs nestjs oauth2 login 유저 경험을 위한 잔꾀부리기 (1) | 2024.03.02 |
nextjs login ui 고민이 있다. (0) | 2024.02.28 |