프로그래머스 데브코스 강의에서 무한스크롤에 대해서 공부했습니다.
이후에 따로 찾아본 내용을 합쳐서 무한 스크롤은 무엇인지, 외에 다른 방법은 없는지, 어떻게 구현하는지를 정리하겠습니다.
구글에 어떤 내용을 검색했을 때
페이스북에서 어떤 내용을 검색했을 때
네이버에서 초콜릿을 살 때
사이트에서 검색된 내용을 전부 한번에 제공해준다면 어떨까요?
컴퓨터로도 많은 데이터를 다 받을 수 있을지 부담이 되는데
핸드폰이라면 이런 걱정이 더 심할것입니다.
첫번째 데이터가 제가 원하는 데이터일 경우 뒤 데이터는 굳이 받을 필요가 없습니다.
사용자에게 찾으려는 데이터를 다 보여주지 않고, 일부를 보여주고 더 보고싶으면 더 보라고 하는쪽이 사용자에게 더 좋을것입니다.
사용자에게 데이터를 보여주는 방법에는 일반적으로 페이지와 무한스크롤이 있습니다.
트위터와 같은 SNS에서 자주 쓰이는 방법으로 스크롤을 내리는 행위를 통해 추가적인 데이터를 불러오는 기법입니다.
정확히는 스크롤을 끝까지 내렸을 때 다음 데이터를 가져오는식으로 계속해서 스크롤을 내릴 수 있게 합니다.
게시글 10개를 기본으로 보여주고, 더 보고싶으면 스크롤을 내리면 됩니다.
무한스크롤은 SNS의 발달로 등장하게 되었습니다.
인터넷의 글도 하루에 몇만개가 생기지만, SNS는 이보다 더 심합니다.
게시글, 댓글, 끊임없는 실시간 소통으로 SNS 사용자는 일반 인터넷 사용자보다 컨텐츠를 읽고, 쓰는 양이 어마어마합니다.
또한 UX도 한 몫 했습니다.
SNS는 모바일 환경에서 주로 사용하는데 클릭보다 더 편한 사용자 경험이 요구되었습니다.
이로 인해 단순하게 스크롤을 내리는 것으로 새로운 컨텐츠를 볼 수 있는 무한스크롤이 떠오르게 됩니다.
무한 스크롤 이전에 쓰이던 기법으로 페이징, 페이지네이션 등 용어는 다양할 수 있으나 개수나 카테고리 등 데이터를 일정 기준으로 나눠서 보여주는 것을 페이지 라고 합니다.
기본으로 1페이지를 보여주고, 더 보고싶으면 2페이지나 3페이지를 클릭하면 됩니다.
위 페이지 설명에서 무한 스크롤 이전에 쓰이던 기법이라고 설명했지만, 페이지는 현재도 쓰이고 있습니다.
무조건 무한스크롤이 좋은것은 아닙니다.
각각 장단점이 있기 때문에 적재적소에 사용해야 합니다.
1. 페이지를 따로 넘기지 않고 (방해 요소 없이) 컨텐츠를 보여줄 수 있습니다
=> 유저에게 더 많으느 컨텐츠를 보도록 유도 가능
2. 모바일 환경에 적합합니다.
1. 현재 위치가 명확하지 않습니다.
=> 뒤로가기 이후 앞으로가기, 새로고침 등 전에 보고 있던 스크롤까지 다시 이동해야 하는데 이 때 어려움이 있습니다.
=> 한번에 초기화면 (1페이지) ~ 보고 있던 스크롤까지의 데이터를 요청해야 합니다.
2. 로드할 데이터가 없음을 명시해줘야 합니다.
=> 로딩중이라는 표시는 페이지에도 필요하지만, 무한 스크롤은 뒤에 더 내용이 있는지 없는지 모르기 때문에 데이터가 없음을 명시해줘야 합니다.
3. Footer를 사용할 수 없습니다.
=> 스크롤을 내리면 Content가 계속 생기기 때문에 Footer에 접근할 수 없습니다.
=> Footer를 고정해서 접근할 수 있도록 조치하거나, Footer 내용을 상단이나 좌우측에 배치해야 합니다.
4. 성능이 저하됩니다.
=> 한 페이지에 많은 데이터를 보여주게 되므로 페이지 성능이 저하됩니다.
5. 실제 사용시에는 로딩중일 때 요청을 보내지 않도록 추가 조치가 필요합니다.
페이지는 1페이지 클릭 시 데이터 한번 받아오고 끝입니다.
하지만 무한 스크롤은 스크롤을 내릴 때 요청을 보내기 때문에 무한으로 요청을 보내게 될 수 있습니다.
이를 위해서 요청을 이미 보내는 중이면 이후에 스크롤을 내려도 요청을 보내지 않도록 조치해야 합니다.
이런 기법을 쓰로틀링이라고 하는데 관련 내용은 추후에 디바운스와 함께 다시 작성하겠습니다.
1. 명확한 현재 위치
=> 이로 인해 어느정도 예측도 가능합니다.
=> 검색 결과 7페이지까지 있으니 다 읽으면 몇분 걸리겠구나
2. 전환
=> 현재 위치가 명확하기 때문에 뒤로 가기, 앞으로 가기 등에도 문제가 없습니다.
1. 클릭이라는 추가 작업은 스크롤을 내리는 것에 비해 귀찮다
=> 사용자 경험이 스크롤과 비교했을 때 더 안좋습니다.
일반적으로 API 요청시 n개씩 끊어서 요청합니다.
1페이지는 1~20, 2페이지는 21~40과 같은식으로 요청하고, 응답 데이터를 사용자에게 보여줍니다.
코드는 생략합니다.
무한 스크롤은 스크롤을 하단 끝까지 내렸을 때 추가 Content를 생성한다는것을 기억하세요.
방법은 일반적으로 2가지가 있습니다.
- window scroll event
scroll 이벤트에 대해서 window.innerHeight + window.scrollY
와 document.body.offsetHeight
를 비교합니다.
window.innerHeight는 브라우저에서 북마크 같은것을 뺀 화면의 세로 길이를 뜻합니다.
window.scrollY는 얼마나 스크롤을 내렸는지를 뜻합니다.
두 값의 합이 body의 전체 Height보다 크면 화면을 끝까지 내린것으로 판단합니다.
위 codepen은 제가 임시로 구현한 window scroll event 무한스크롤입니다.
기본으로 5개의 div가 있고, 스크롤을 아래로 거의 내리면 div를 5개 더 생성하는식으로 15개까지 생성할 수 있습니다.
꼭 반드시 맨밑에 가야 생기는건 아니고 어느 정도 유연성 있게 하기 위해 200을 추가했습니다.
- Intersection Observer
window scroll event와 js만 다릅니다.
InterSecionObserver는 특정 DOM 요소가 viewport에 들어왔는지를 판단하는 API입니다.
DOM 사이의 거리를 측정해야 하는 경우가 있었고, 웹이 발달하며 해당 기능이 내부 API로 생기게 되었습니다.
const observer = new IntersectionObserver(callback, option)
observer.observe(DOM)
observe() 메소드로 특정DOM을 관측하도록 하면, DOM이 viewport에 들어왔는지 안들어왔는지 판단합니다.
codepen의 js코드를 보시면 마지막 div가 viewport에 들어왔을 때
추가로 div를 생성하고 있습니다.
옵저버는 여러개의 DOM을 관측할 수 있으니 조심!
observe() 메소드로 5번째 div를 관측하고 있을 때, 10번까지 div를 추가 생성하고, 10번째 div를 관측합니다.
하지만 5번째 div도 여전히 관측하고 있기 때문에 스크롤을 올렸다가 내리면 15번까지 div가 생깁니다.
이를 위해 기존의 dom은 unobserve() 메소드로 관측을 해제해야 합니다.
option 주의
option의 threshold 값은 0일 경우 조금만 viewport에 들어와도 감지되지만, 1일 경우 완전히 들어와야 감지됩니다.
정리
무한스크롤과 페이지에 대해서 공부했습니다.
무한스크롤은 예제 codepen이 있으니 참고부탁드립니다.
무한 스크롤이 반드시 좋지는 않습니다.
대부분 SNS에 많이 사용되고 현재도 구글, 네이버 등은 페이지를 사용하고 있습니다.
사용자에게 어떤 데이터를 어떻게 제공할지, 어떤 경험이 좋을지 잘 생각하고 적재적소에 무한스크롤을 사용해야겠습니다.
참고
오늘의 집 - 오늘의집 내 무한 스크롤 개발기
hellodigital - 페이지네이션 VS 무한스크롤 : 자사에 적합한 UX 고르는 법 /2
mdn docs IntersectionObserver
브런치 - UX : 무한 스크롤과 페이징
slowalk.com - 무한 스크롤 vs 페이지네이션