개발 slecs

읽기 경험 개선으로 포스트 체류율 높이기

목차

포스트 페이지에 사용자 체류 관련 위젯들을 한데 묶어서 3컬럼 센터드 레이아웃으로 배치했다. 단순한 UI 리프레시가 아니라, 독자가 한 글을 읽은 후에 다음 콘텐츠로 자연스럽게 흘러갈 수 있도록 의도적으로 설계한 작업이다.

왜 retention widgets 가 필요했나

기존 포스트 페이지는 글 본문과 기본 메타정보(제목, 날짜, 작성자)만 있었다. 독자 입장에서는 한 글을 다 읽으면 떠나야 했다. 하지만 사용자 행동 분석을 보니, 잠시 머물렀다가 나가는 패턴이 명확했다. 우리는 여기서 두 가지 기회를 놓치고 있었다. 첫째, 방금 읽은 글과 관련된 다른 콘텐츠들을 바로 옆에 두면 자연스럽게 다음 클릭이 유도된다. 둘째, 독자가 지금까지 방문한 경로(최근 본 글, 읽기 진행도)를 시각화하면 심리적 만족감이 높아진다.

그래서 네 가지 위젯을 추가하기로 결정했다:
- ReadingProgress: 현재 글의 읽기 진행률을 시각적으로 표시
- RecentlyViewed: 이번 방문에서 봤던 이전 포스트 목록
- RelatedPosts: 알고리즘 기반 관련 글 추천
- TableOfContents: 긴 글의 경우 네비게이션 가능하도록 목차 제공

3컬럼 센터드 레이아웃의 의도

처음에는 이 네 위젯을 본문 옆에 우측 사이드바로 스택할 생각도 했다. 하지만 그렇게 하면 모바일에서는 스크롤이 길어지고, 데스크톱에서도 위젯들끼리 시각적 계층이 흐트러진다. 대신 3컬럼 센터드 구조를 택했다:
- 중앙: 포스트 본문 (1컬럼)
- 좌측: TableOfContents (고정)
- 우측: ReadingProgress + RecentlyViewed + RelatedPosts (스택)

이 레이아웃의 장점은:
1. 데스크톱 가독성: 본문이 최적 폭으로 유지되고, 양쪽 보조 정보가 대칭적으로 배치
2. 모바일 적응성: 좁은 화면에서는 자동으로 스택 레이아웃으로 전환 가능
3. 발견성 극대화: 독자의 눈이 자연스럽게 관련글 → 최근 본 글로 흐르도록 유도

데이터베이스 쿼리 최적화는 필수

src/lib/db.ts 를 함께 수정한 이유는, 이 위젯들이 실시간 데이터를 필요하기 때문이다. RecentlyViewed는 사용자 방문 히스토리를 조회해야 하고, RelatedPosts는 태그나 카테고리 기반 유사 포스트를 찾아야 한다. 예전 방식이라면 페이지 렌더링 시마다 여러 쿼리를 날렸을 텐데, 이번엔 데이터베이스 레이어에서 이들을 통합하거나 캐싱하는 로직을 추가했다.

여기서 중요한 결정이 있었다: 이 데이터들을 build-time에 생성할 건가, 아니면 request-time에 동적으로 가져올 건가? RecentlyViewed는 분명 사용자별로 다르므로 request-time 필수. 하지만 RelatedPosts는 글이 변하지 않으면 항상 같으므로 build-time 생성 후 캐시 가능. 이 구분이 결국 데이터베이스 쿼리 부하와 직결된다.

조직 관점에서의 배움

이 작업을 추진하면서 팀과 함께 고민한 부분들:
- 우선순위 결정: 새 기능 추가보다 기존 사용자의 체류 개선이 먼저라는 합의
- 컴포넌트 설계: 각 위젯(ReadingProgress, RecentlyViewed 등)을 독립적으로 개발하되, Post 레이아웃에서만 조합하는 구조. 이렇게 하면 나중에 위젯을 재배치하거나 제거할 때 영향도가 최소화된다.
- 성능 고민: 4개 위젯이 동시에 데이터를 요청하면 렌더링이 느려질까? 이는 db.ts 최적화와 연결된 부분이다.

회고해보니, 이런 타입의 작업은 "구현"만큼 "왜 이 순서인지", "다른 방법은 없을까"를 설득하는 게 절반이다. 팀장 입장에서는 단순히 코드를 머지하는 게 아니라, 이 레이아웃 변경이 향후 분석 데이터(체류 시간, 클릭률)에 어떻게 반영될지까지 함께 체크해야 한다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.