사이드프로젝트 slecs

프로필 페이지 리디자인으로 체류 시간 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

첫 댓글 달아줘.