새발블로그
SPA 환경에서 이탈률(Exit/Bounce)·체류시간(Dwell)을 정확히 측정하는 방법 본문
1. 왜 SPA에서 이탈률 측정이 어려운가?
일반 웹페이지는 새로고침마다 페이지가 다시 로드되므로 page_view·page_leave 타이밍이 명확
반면 SPA는:
- 라우팅 전환 시 브라우저는 그대로, 콘텐츠만 바뀜
- 컴포넌트가 실제로 unmount되지 않을 수도 있음(keep-alive)
- 전환 애니메이션, 레이아웃 구조에 따라 이벤트 호출 타이밍이 달라짐
결과적으로 dwell(체류시간) 또는 bounce(빠른 이탈) 계산이 왜곡될 수 있음
2. 이탈률을 계산하기 위한 핵심 이벤트 정의
page_view
사용자가 특정 라우트에 진입하는 순간
- 기록 정보: ts(타임스탬프), page
page_leave
사용자가 해당 라우트에서 떠나는 순간
- dwellMs = leave.ts - view.ts
- dwellMs < threshold(예: 5000ms) → bounce
action
버튼 클릭, CTA, 모달 열기 등 의미 있는 행동
{ "type": "page_view", "page": "chart", "ts": 1731200 }
{ "type": "action", "page": "exit", "action": "open_modal", "ts": 1731202 }
{ "type": "page_leave", "page": "exit", "ts": 1731204, "dwellMs": 4200 }

3. Vue 컴포넌트 라이프사이클을 활용한 측정
2025.05.04 - [Client/Vue.js] - [Vue.js] Vue 생명주기
[Vue.js] Vue 생명주기
펻 컴포넌트는 생성되고, DOM에 부착되고, 업데이트 되며, 결국 소멸한다. 이 일렬의 과정을 생명주기라고하며, 각 단계에서 특정 함수를 실행할 수 있는 라이프사이클 훅이 존재한다. 1. Vue 생명
2uwls.tistory.com
슬쩍 끼워넣기 ㅎ
onMounted()
- 컴포넌트가 화면에 처음 나타나는 순간
- 페이지가 사용자에게 보이는 시점이므로 page_view 기록에 적합
onBeforeUnmount()
- 컴포넌트가 DOM에서 사라지기 직전
- 여기서 page_leave(dwell 포함) 기록
예제:
onMounted(() => {
enterTs.value = Date.now();
push({ type:'page_view', page, ts: enterTs.value });
});
onBeforeUnmount(() => {
const leave = Date.now();
push({ type:'page_leave', page, ts: leave, dwellMs: leave - enterTs.value });
});
4. KeepAlive에서의 문제점
<keep-alive> 컴포넌트는 unmount되지 않기 때문에 onBeforeUnmount()가 호출되지 않음 → dwell 계산 누락
해결책
- onActivated() → 진입 시점
- onDeactivated() → 이탈 시점
또는 아래 라우터 훅 보정을 함께 사용하는 것이 가장 안정적
5. 라우터 훅으로 leave/view 정확도 보정
SPA에서 가장 신뢰할 수 있는 방식은 라우터 전환이 일어나는 순간을 직접 캡처하는 것
router.beforeEach((to, from, next) => {
if (from?.name) analyticsPushLeaveFor(from.name);
next();
});
router.afterEach((to) => {
analyticsPushViewFor(to.name);
});
추가로 탭 닫힘/새로고침에 대한 보강:
window.addEventListener('pagehide', () => {
analyticsPushLeaveFor(currentRoute);
});
6. 이탈률 분석을 위한 지표 설계
| 지표 | 설명 |
| Leaves | page_leave 발생 수 |
| Bounces | dwell < threshold (예: 5초) |
| Bounce Rate | Bounces / Leaves |
| Median Dwell | dwell 중앙값(평균보다 안정적) |
| p90 / p95 Dwell | 사용자 흐름 지연 탐지 |
| Active Users | (액션 발생 or dwell ≥ N초) 사용자 |
7. 개선 프로세스
- 수집: page_view/leave/action 로그 누적
- 탐지: bounce↑, median dwell↓ 페이지 찾기
- 가설:
- 원하는 정보 없음
- 페이지 구조 복잡
- 느린 API로 초기 렌더 지연
- 수정:
- UI 재배치/카피 개선
- 코드 분할 & lazy-loading
- 초기 API 최소화
- 검증: 전/후 성능 비교 또는 A/B 테스트
'Client > Vue.js' 카테고리의 다른 글
| D3로 값 범위(Orders-of-Magnitude)가 큰 시계열을 정확하게 시각화하는 방법 (0) | 2025.11.10 |
|---|---|
| [Vue.js] Pinia로 Vue 상태 관리하기 (0) | 2025.05.04 |
| [Vue.js] Vue 3에서 API 호출은 언제 하는 게 맞을까? (0) | 2025.05.04 |
| [Vue.js] Vue 생명주기 (0) | 2025.05.04 |
| [Vue.js] Composition API (0) | 2025.05.04 |