-
모바일 환경에서 무한스크롤을 사용하는 이유가 뭘까? feat. cursor based pagination #1Flutter/study 2024. 2. 12. 12:03
유저에게 보여줘야할 데이터 목록이 많은 경우, 한번에 모든 데이터를 보여주는 것은 DB 조회비용도 많이 들 뿐더러서버 및 클라이언트에 부하를 일으켜 성능저하로 이어집니다. 그렇기때문에 대량의 데이터를 처리하는 대다수의 어플리케이션은 유저에게 많은 데이터를 리스트형태로 보여줄때, 필수적으로 pagination이라는 기법을 사용합니다. 이번에는 페이지네이션이 무엇인지, 그리고 실제로 제가 도입한 과정들을 정리하는 시간을 가져보겠습니다.
✓ Pagination이란?
"목록화된 많은 데이터를 부분적(페이지 단위)으로 나눠서 불러오는 기술"
유튜브에는 엄청나게 많은 영상이 있습니다. 만약 유저가 유튜브 앱 또는 웹사이트를 열었을 때, 한 번에 모든 영상을 불러오려고 하면 어떤 일들이 벌어질까요?
서버입장에서 생각해본다면 유튜브에서 한번에 모든 영상을 불러오면 서버는 엄청난 부하가 걸리게 되면서 서버 응답 속도도 엄청 떨어지게 될 것입니다.
그리고 유저가 원하는 영상을 보기위해 반드시 모든 영상을 불러와야할까요?
예를들어 전체 동영상의 갯수가 100개라고 가정을 해보겠습니다. 유저가 모든 영상을 한번씩 보지않는 이상 굳이 100개의 영상을 보여줄 필요는 없을뿐더러 소수의 영상을 보기위해 100개의 데이터를 불러오는 시간을 기다려야합니다. 이는 사용자 경험을 저하시킬 뿐만 아니라 불필요하게 데이터를 조회하는 비용도 낭비하게 됩니다.
페이지네이션은 위와같은 문제를 해결하기 위해 사용됩니다.
유저에게 조회한 데이터를 나눠서 제공함으로써, 필요한 데이터에 접근할때까지 전체 데이터를 한번에 조회할 필요없이 필요한 페이지로 이동하여 효율적으로 원하는 정보를 찾을 수 있도록 합니다.
페이지네이션은 필요한 데이터만 주고받으며, 데이터 조회 비용을 최소화하고 사용자 경험을 향상시키는 중요한 역할을 합니다.
📌 Page
운영체제(OS)에는 페이징(Paging)이라는 개념이 있습니다. 효율적인 데이터 적재를 위해 논리적 메모리를 동일한 크기로 나누는 것을 의미하는데 이때 나누어진 조각 단위를 페이지라고 부릅니다. 페이지네이션에서 페이지의 의미도 이와 비슷한 개념이라고 볼수있습니다.
페이지의 정의는 다음과 같습니다.
"컨텐츠를 조회할때 한번에 받는 데이터 묶음 단위"
또한 페이지는 여러 페이지네이션을 나누는 기준이 되는데 클라이언트에서 사용되는 페이지의 의미는 UI와 관련있고, 서버에서 사용하는 페이지는 데이터를 나누는 방법과 관련있으므로 페이지네이션에 대한 해석도 서로 다르게 나타납니다.
✓ 클라이언트의 Pagination
클라이언트에서 페이지네이션은 UI가 보여지는 방법에따라 종류가 나뉘어집니다.
대중적으로 사용되는 두개만 알아보도록 하겠습니다.
📌 Page based pagination
네이버 웹사이트를 PC로 접속하면 맨 하단에 여러 페이지 번호가 나열된 페이지 네비게이션을 볼 수 있습니다. 이 페이지 네비게이션을 통해 유저는 원하는 페이지로 이동할 수 있습니다.
페이지 기반 페이지네이션은 유저에게 여러 페이지로 나누어진 데이터를 보여주고, 각 페이지를 클릭하면 해당 페이지에 대한 데이터를 요청하여 표시합니다.
✍🏼 특징
- 유저가 특정 페이지로 직접 이동할 수 있어 데이터를 탐색하기 용이하다.
- 각 페이지마다 고유한 URL을 가지고 있어 검색 엔진이 각 페이지를 쉽게 색인화하고 검색 결과에 표시할 수 있으므로, 검색 엔진 최적화(SEO) 측면에서 유용하다.
이러한 특징 덕분에 페이지 기반 페이지네이션은 대부분의 웹사이트에서 흔히 사용되는 페이지네이션 형태 중 하나로서, 사용자 경험과 검색 엔진 최적화에 기여합니다.
하지만 페이지기반 페이지네이션은 화면이 작고 스크롤 방식을 선호하는 모바일에서 사용하기에는 좋지않습니다.
📌 Infinity scrolling (무한 스크롤)
무한 스크롤은 유저가 스크롤을 하면서 자동으로 새로운 데이터가 동적으로 로드되는 방식을 말합니다. 유저에게 연속적인 컨텐츠를 제공하기때문에 페이지간의 이동없이 부드럽고 중단되지않는 탐색 경험을 줄 수 있습니다.
또한 페이지의 전환없이 스크롤만으로 데이터가 자동 로딩 되므로 별다른 작업이 필요없어 유저의 편의성이 향상되므로 모바일 환경에서 자주 쓰입니다.
클라이언트의 페이지기반 페이지네이션은 백엔드의 오프셋 기반 페이지네이션과 함께 쓰이며, 무한 스크롤은 커서 기반 페이지네이션과 함께 쓰이는 경우가 많습니다. 그럼 페이지네이션 전체 동작 원리를 이해하기 위해 서버측면 페이지네이션에 대해 알아보도록 하겠습니다.
✓ 백엔드의 Pagination
들어가기 앞서 백엔드의 pagiantion은 크게 offset based pagination과 cursor based pagination이 있고 공통적으로 take라는 개념이 있습니다.
take는 페이지와 같은 개념으로 한번에 조회할 데이터의 갯수를 의미합니다.
그럼 바로 알아보도록 하겠습니다.
📌 Offset based pagination
- offset: 가져와야할 데이터의 시작위치를 알려주는 역할을 하며, take 갯수에따라 나눠지기때문에 offset값은 take에따라 계산됩니다. 위의 경우 take=4 이므로 offset은 처음엔 0이었다가 take만큼 늘어나 3, 7, 10 순으로 매겨집니다.
오프셋 페이지네이션은 조회할 데이터의 갯수(Take)와 offset에 집중합니다. 예를들어 세번째 페이지를 불러올때 오프셋 이후부터 4개의 데이터를 조회하기때문에 '9, 10, 11, 12'를 집어서 가져오게 됩니다.
하지만 이러한 방식은 특정 상황에서 문제점이 발생하게됩니다.
✍🏼 이전 페이지에 Data가 추가된 경우
아까 세번재페이지에서 "9,10,11,12"데이터를 조회하고 난후에 다음페이지를 보려고 하기전에 현재 offset 범위보다 적은 곳에 새로운 데이터가 추가된 경우입니다.
우리는 이미 이전에 '12'라는 데이터를 봤었습니다. 그런데 다음 페이지를 조회하는 아까봤던 12 데이터가 또 노출되었습니다. 예시처럼 1개만 추가되어서 하나만 중복된다면 크게 불편함을 느끼지 못하겠지만 페이지 크기 이상 추가가 된다면 유저입장에서는 불편하다고 느낄수도 있습니다.
✍🏼 이전 페이지에 Data가 삭제된 경우
반대로 다음페이지를 조회하기 전에 이전 페이지의 데이터가 삭제된 경우는 어떨까요? 유저는 "9, 10, 11, 12" 데이터를 조회했기때문에 "13" 데이터부터 볼 것을 기대하고있습니다. 하지만 삭제된 만큼 데이터가 앞으로 당겨져, 실제로 "14, 15, 16, 17" 데이터를 보게됩니다.
마치 "13" 데이터가 유실된 것처럼 느껴집니다.
자주 데이터가 추가되고 삭제되지않는 경우에 오프셋기반 페이지네이션은 구현 방법도 간단해 좋은 선택지가 될수있습니다. 하지만 만약 무한 스크롤을 구현했는데 이렇게 자주 데이터가 추가되고 삭제된다면 유저는 서비스를 이용하는데 큰 불편함을 느낄 수 있습니다.
이러한 단점을 보안하고자 고안된 방법이 바로 cursor based pagination입니다.
📌 Cursor based pagination
커서는 마치 포인터와 비슷하게 동작되게끔 구성되어야합니다.(ex. 타임스탬프 활용)
그리고 서버는 유저마다 다른 커서값을 일일이 기억 할 수 없기때문에 데이터를 조회할때마다 마지막 커서값을 클라이언트에게 함께 전달합니다.
클라이언트 입장에서는 마지막 데이터를 기준으로 다음 데이터를 받는 것과 같이 동작되기때문에 연속된 데이터를 보여주는 무한 스크롤에 적합한 방법입니다.
✍🏼 이전 페이지에 Data가 추가된 경우
커서를 기반 페이지네이션은 커서를 기준으로 다음 데이터를 take만큼 불러옵니다. 일반적인 상황과 새로운 데이터가 추가된 경우는 오프셋 기반 페이지네이션과 다른 점이 없습니다.
✍🏼 이전 페이지에 Data가 삭제된 경우
커서 기반 페이지네이션은 유저가 다음 페이지를 요청할 때 서버로 보낸 마지막 커서는 "12" 데이터가 삭제되었는지 여부와 관계없이 있었던 "자리"를 기억하고 있습니다. 서버는 이 커서를 사용하여 다음 페이지의 데이터를 가져오는데, 그 위치부터 시작하여 다음 데이터 4개를 조회해서 전달합니다. 따라서 유저는 "13" 데이터부터 "16"까지의 데이터를 받을 수 있습니다.
이처럼 데이터 조회 시, 커서 기반 페이지네이션은 이전 페이지의 데이터가 삭제되었더라도 유저가 요청한 페이지를 끊김없이 제공할 수 있습니다. 그렇기때문에 주로 무한 스크롤과 같이 연속적으로 데이터를 보여주어야 하는 모바일 환경에서 사용됩니다.
모바일 환경에서 무한 스크롤을 사용하는 이유와 무한 스크롤을 구현할 때, 커서기반 페이지네이션을 이용해야한다는 것을 알아보았습니다.
이어서 다음 글에서는 Flutter을 이용해 어떻게 무한 스크롤을 구현하는지 알아보도록 하겠습니다.
긴글 읽어주셔서 감사합니다
[Flutter] 무한 스크롤 구현해보기 feat. cursor based pagination #2
*이 글의 페이지네이션 로직은 코드팩토리님의 강의 내용을 응용하여 제작되었습니다. 모바일 환경에서 무한스크롤을 사용하는 이유가 뭘까? feat. cursor based pagination #1 유저에게 보여줘야할 데
nomal-dev.tistory.com
이 글이 꼭 정답은 아닙니다. 잘못된 부분이나 부족한 부분을 알려주시면 학습 후 수정하겠습니다.
'Flutter > study' 카테고리의 다른 글
JWT를 이용한 인증·인가 프로세스에대해 낱낱히 파헤쳐보자! feat. 토큰, 세션 (2) 2024.02.02 [Flutter] '상태'관리는 어떻게 해야할까요? feat. sealed class (4) 2024.01.24