← 포트폴리오로 돌아가기

MyPortfolio

2025.07 ~ 2024.08

개발 인원: 1명

프로젝트 소개

MyPortfolio는 제가 프론트엔드 개발자로서 쌓아온 기술 역량과 프로젝트 성과를 한눈에 보여주기 위해 제작되었습니다. 각 프로젝트는 사용된 기술 스택, 구현 기능, 그리고 해결했던 문제를 구체적으로 담고 있습니다. GitHub 저장소와 배포 링크를 통해 제 코딩 스타일과 결과물을 직접 확인할 수 있으며, 도메인이 만료된 프로젝트는 데모 영상을 통해 실제 동작을 확인하실 수 있습니다. 사용자(방문자)가 제 개발 스타일을 쉽게 파악하고, 포트폴리오를 통해 저의 잠재력을 느낄 수 있도록 사용자 경험(UX)에 집중했습니다.

기술 스택

Tailwind logoTailwind
TypeScript logoTypeScript
React logoReact
NextJs logoNextJs

주요 작업

인터셉팅 라우트를 활용한 프로젝트 상세 모달 구현

SEO 최적화와 링크 공유 가능성을 위해 기존 상태 기반 모달에서 Intercepting Routes로 전환했습니다.

  • Next.js의 Intercepting Routes 기능을 활용하여 프로젝트 상세 모달이 고유 URL을 가지도록 구현
  • 각 프로젝트에 대한 직접 링크 공유 및 검색 엔진 인덱싱 가능 → SEO 성능 향상
  • 모달 URL 접근 시에도 동일한 UI 유지로 사용자 경험 최적화

이미지 렌더링 최적화를 통한 UX 및 성능 향상

Next.js 앱에서 이미지 지연 로딩 및 깜빡임 현상을 해결하고, Vercel CDN 캐시 활용을 통해 LCP를 약 48% 단축하는 등의 성능 최적화를 달성했습니다.

  • vercel.json을 통해 public 폴더 내 정적 이미지에 대한 강력한 CDN 캐시 정책을 적용
  • 모달 전후 이미지 재로딩 이슈를 해결하여 모달 전환 시 이미지 깜빡임 제거
  • 이미지 로딩 시간을 약 86.7% 단축(450ms → 59.73ms)하고, LCP 약 48% 개선 (2.3s → 1.2s), 그리고 CDN 캐시 HIT율을 90% 이상으로 향상

라우트 프리페칭 기반 프로젝트 상세 모달 로딩 최적화

모달 표시 지연 문제를 해결하기 위해 Next.js의 router.prefetch를 활용하여 프로젝트 상세 페이지 관련 리소스를 사전에 로드하는 전략을 도입했습니다.

  • 카드에 마우스 오버/포커스 시 해당 상세 페이지 라우트를 미리 로드하도록 구현
  • 컴포넌트 마운트 시 모든 프로젝트 경로를 백그라운드에서 프리페칭하여 클릭 시 로딩 시간 최소화
  • 모달 렌더링 관련 스크립트 실행 시간을 약 41% 감소시키고, 모달을 포함한 페이지의 전체 이벤트 시간을 약 30% 단축(5,478ms → 3,844ms)

Storybook 도입을 통한 UI 컴포넌트 문서화 및 시각 테스트 적용

실무 도입 전 사전 경험을 위해 Storybook을 사용하여 UI 컴포넌트를 문서화하고 시각적 테스트를 진행했습니다.

  • 컴포넌트 단위 문서화를 통해 UI 구성 요소를 독립적으로 테스트하고 구조화된 개발 환경을 경험
  • 독립된 환경에서 시각적 피드백을 빠르게 확인하고, 디자인 일관성 유지에 도움이 되는 워크플로우를 체험

CI 파이프라인 구축 및 시각/정적 테스트 자동화

코드 품질 보장과 배포 전 자동 검증을 위한 CI 파이프라인을 구성했습니다.

  • GitHub Actions 기반 CI로 lint, build, typecheck 자동화
  • Chromatic 연동을 통한 시각 회귀 테스트로 UI 변경 자동 감지
  • Storybook 기반 접근성 테스트 환경 구성 및 조건부 실행 처리

Google Analytics 도입을 통한 방문자 데이터 분석

SEO 설정 후 실제 검색 노출 및 방문자 변화 추이를 데이터 기반으로 측정하기 위해 Google Analytics를 도입했습니다.

  • 포트폴리오 프로젝트에 robots.txt, sitemap.xml, metadata, 구조화 데이터(Structured Data)를 적용한 뒤 변화 측정을 위해 Google Analytics 연동
  • 실시간 방문자 수, 유입 경로, 페이지별 조회수를 추적하여 SEO 효과를 수치로 검증
  • GA4의 이벤트 추적 기능을 통해 프로젝트 상세 모달 열기, 외부 링크 클릭 등 사용자 행동 데이터 수집
  • 분석 데이터 기반으로 UI·콘텐츠 개선 방향 도출 및 향후 SEO 전략 수립

Supabase 기반 방문자 수 카운터 구현

Google Analytics 같은 외부 분석 도구를 사용하지 않고, Supabase를 활용해 방문자 수를 자체적으로 집계·표시할 수 있는 기능을 구현했습니다.

  • Supabase DB와 연동하여 하루 단위·총 방문자 수를 집계 및 누적 기록하는 로직 구축
  • 서버에서 최신 데이터를 가져올 때 숫자 카운트업 애니메이션을 적용해 직관적이고 역동적인 UX 제공
  • fetch(..., { cache: "no-store" })를 적용해 항상 서버의 최신 방문자 수를 반영, 캐시된 오래된 데이터 문제 방지
  • 외부 분석 도구 의존도를 낮추고, 운영 효율성과 서비스 독립성 강화

EmailJS 연동을 통한 피드백 폼 구현

방문자가 포트폴리오에 대해 피드백을 남길 수 있도록 서버리스 메일 전송 기능 구현했습니다.

  • EmailJS를 활용하여 별도 서버 없이 사용자 입력 내용을 이메일로 수신
  • 간편하고 빠른 구현으로 사용자 커뮤니케이션 채널 확보

ScrollToButton 구현으로 페이지 탐색 편의성 제공

상/하단 이동이 자유로운 버튼 구현으로 사용자의 편의성을 향상시켰습니다.

  • 스크롤 위치 감지를 통해 버튼 방향을 동적으로 전환하는 UX 구현
  • 상단/하단 이동을 직관적으로 처리하여 페이지 탐색 편의성 향상

트러블슈팅

모달 전환 후 이미지 재렌더링 지연 및 깜빡임 현상 해결

📌 문제 배경

프로젝트의 ProjectsSection에서 카드 클릭 시 모달이 열리고 닫히는 구조였는데, 모달 종료 후 카드 이미지가 다시 렌더링되면서 이미지 깜빡임지연 로딩 현상이 발생했습니다.

🔍 원인 분석

  • public 폴더 이미지 사용 시 next/image의 최적화 기능이 적용되지 않음
  • 모달이 닫힐 때 이미지가 다시 렌더링되면서 네트워크 요청이 반복됨
  • 브라우저나 CDN에서 캐시가 충분히 작동하지 않아, 이미지가 깜빡이거나 느리게 나타남

🛠 해결 과정

  1. vercel.json을 통한 정적 이미지에 대한 캐시 정책 강화
    • vercel.json 설정 파일을 추가하여 public 폴더 내 이미지 파일에 대해 max-age=31536000, immutable 설정을 적용
    • Vercel CDN을 통해 정적 이미지 리소스가 1년간 캐싱되도록 설정하여, 반복 요청 시 캐시에서 즉시 로딩되도록 개선
    • 모달 종료 후에도 이미지가 네트워크가 아닌 캐시에서 로딩되어 깜빡임 없이 즉시 렌더링되도록 처리

✅ 결과

  • 이미지 로딩 시간 450ms → 59.73ms로 약 86.7% 단축
  • CDN 캐시 HIT율 10~20% → 90% 이상으로 약 4~9배 향상
  • LCP 2.3초 → 1.2초로 약 48% 성능 개선
  • 모달 전환 시 이미지 깜빡임 제거로 사용자 경험 향상

🧠 배운 점

이미지 최적화를 통해 성능 지표를 실질적으로 개선할 수 있다는 점을 체감하였고, 특히 public 이미지 리소스도 vercel.json을 통한 캐시 정책으로 성능 최적화가 가능하다는 것을 학습했습니다. 프론트엔드 성능 향상에서 정적 자원의 캐시 전략 수립이 매우 중요한 요소임을 실무적으로 경험했습니다.

프로젝트 상세 모달 전환 시 초기 로딩 지연 문제 해결

📌 문제 배경

기존 ProjectsSection에서 카드 클릭 시, 모달 관련 컴포넌트와 라우트 번들이 즉시 로드되었습니다. 이로 인해 스크립트 컴파일, 평가, 레이아웃 계산 등 여러 작업이 클릭 시점에 한꺼번에 발생하여 모달이 포함된 페이지의 전반적인 반응 속도가 느려졌습니다. 전체 이벤트 총 시간은 약 5.48초에 달했습니다.

🔍 원인 분석

  • 모달 진입 시점에 필요한 자바스크립트 번들이 네트워크에서 즉시 로드되어 병목 현상 발생
  • Next.js의 라우터 프리페치(router.prefetch) 기능이 활용되지 않아 사전 로딩이 이루어지지 않음
  • 스크립트 컴파일 및 평가, 레이아웃 재계산 등 연산 작업이 클릭 시점에 집중되어 UI 표시 지연

🛠 해결 과정

  1. 사용자 행동 기반 라우트 사전 로드 구현
    • 사용자가 프로젝트 카드에 마우스 오버(onMouseEnter)하거나 포커스(onFocus)할 때 해당 프로젝트의 상세 경로를 router.prefetch로 미리 로드하도록 구현
    • 컴포넌트가 마운트될 때 useEffect를 활용, 현재 화면에 보이는 모든 프로젝트 경로를 백그라운드에서 순차적으로 프리페칭

✅ 결과

  • 모달을 포함한 전체 이벤트 총 시간: 5,478ms → 3,844ms로 약 29.7% 단축
  • 모달 렌더링 관련 스크립트 실행 시간: 237.7ms → 138.3ms로 약 41.8% 감소
  • 스크립트 컴파일 시간: 253ms → 148ms로 약 41.4% 감소
  • 스크립트 평가 시간: 233.5ms → 126.3ms로 약 45.9% 감소
  • 네트워크 요청 지연 해소로 사용자 클릭 반응성 및 모달 전환 속도 체감 향상

🧠 배운 점

Next.js의 router.prefetch 기능을 적절한 시점(사용자 행동 예측)에 호출하는 전략이 전반적인 페이지 전환 속도와 모달 렌더링 시간을 모두 개선할 수 있음을 확인했습니다. 특히, 컴포넌트 마운트 시와 사용자 인터랙션 발생 시점을 활용한 선택적 프리페칭 전략이 성능 최적화에 매우 효과적인 방법임을 경험했습니다.