프로필 페이지 리디자인으로 체류 시간 3배 늘린 과정
목차
프로필 페이지 갈아엎은 날
오래 묵힌 프로필 페이지를 손봤음. 기존 페이지는 정적인 카드 한 장에 이름·소개·연락처만 박아둔 형태였는데, 방문자가 1초 보고 바로 닫는다는 피드백이 누적돼서 작정하고 리디자인 들어감.
목표는 세 가지였음.
- 첫 화면 진입 시 시선 잡아끄는 모션
- 보유 스킬을 한눈에 파악 가능한 아이콘 그리드
- 누적 활동량을 보여주는 통계 카운터
모션 설계
처음엔 라이브러리 깔까 고민했는데, 카드 페이드인 + 카운터 증가 + 호버 정도면 CSS 트랜지션과 IntersectionObserver 조합으로 충분하다고 판단함. 번들 크기 안 늘리는 게 이득.
.skill-card {
opacity: 0;
transform: translateY(16px);
transition: opacity .5s ease, transform .5s ease;
}
.skill-card.is-visible {
opacity: 1;
transform: translateY(0);
}
스크롤 진입 시점에 is-visible 토글하는 옵저버 한 개로 모든 카드를 처리함. 카드별로 transition-delay 를 80ms 씩 어긋나게 줘서 계단식으로 등장하게 했더니 훨씬 살아있는 느낌.
스킬 아이콘 그리드
이미지 스프라이트 vs 인라인 SVG 고민했는데, 호버 시 색상 톤만 바꾸는 인터랙션이 필요해서 인라인 SVG 로 통일.
| 항목 | 기존 | 개편 후 |
|---|---|---|
| 첫 화면 LCP | 2.4s | 1.6s |
| 평균 체류 시간 | 11s | 38s |
| 스킬 영역 클릭률 | 측정 불가 | 27% |
체류 시간이 3배 이상 늘어난 게 제일 큼. 스킬 카드를 클릭하면 해당 스킬로 진행한 사이드 프로젝트 링크로 이동하게 묶었는데, 이 동선이 먹혔다고 봄.
통계 카운터
누적 커밋·블로그 글 수·관여한 프로젝트 수를 카운트업 애니메이션으로 노출. 숫자가 0에서 목표값까지 1초간 증가하는 흔한 패턴.
const animate = (el, target) => {
const start = performance.now();
const tick = (now) => {
const p = Math.min((now - start) / 1000, 1);
el.textContent = Math.floor(target * p).toLocaleString();
if (p < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
};
처음엔 setInterval 로 짰다가 탭 비활성 상태에서 타이밍 어긋나서 requestAnimationFrame 으로 갈아탐. 백그라운드 진입 시 자동 정지되는 게 깔끔함.
삽질 포인트
- 모션 한꺼번에 트리거하면 첫 진입에서 GPU 점유가 튐 →
will-change남발 금지, 카드별 지연으로 분산 - prefers-reduced-motion 미디어 쿼리 빠뜨려서 접근성 리뷰에서 지적당함 → 즉시 추가
- 카운터 목표값을 빌드 시점에 박아두니 수동 갱신 부담 → 정적 JSON 로 분리해서 배포 파이프라인에서 갱신
회고
리디자인의 ROI 는 예상보다 컸음. 코드량 대비 체감 임팩트가 가장 높은 작업이었고, 무엇보다 "내가 뭘 하는 사람인지" 가 페이지 한 장에서 명확히 전달되도록 정리한 효과가 컸다고 봄. 라이브러리 안 쓰고 버틴 것도 잘한 결정.
다음
댓글 0
첫 댓글 달아줘.