← 포트폴리오로 돌아가기

MyPortfolio

2025.07 ~ 2025.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% 이상으로 향상

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

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

  • IntersectionObserver를 활용해 카드가 뷰포트 근처(100px 이내)에 들어올 때 상세 페이지 라우트를 자동 프리페칭
  • 카드에 마우스 오버/포커스 시점에도 router.prefetch를 호출하여 사용자 행동 기반 사전 로딩 보완
  • 모달 렌더링 관련 스크립트 실행 시간을 약 41% 감소시키고 모달을 포함한 페이지의 전체 이벤트 시간을 약 30% 단축(5,478ms → 3,844ms)

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

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

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

Jest + RTL 기반 단위/통합 테스트 적용

JestReact Testing Library를 도입해 단순한 동작 확인을 넘어 실제 사용자 경험과 가까운 시나리오까지 검증했습니다. 컴포넌트 단위의 안정성과 사용자 흐름 단위의 신뢰성을 동시에 확보하며 프로젝트 품질을 한 단계 끌어올렸습니다.

  • 단위 테스트: 다양한 UI 이벤트상태 변화를 세밀하게 검증해 리팩토링 이후에도 동일한 동작을 유지할 수 있도록 품질 확보
  • 통합 테스트: API 요청 → 데이터 반영 → 최종 UI 표시의 흐름을 실제 시나리오로 검증해 사용자 경험 신뢰성 강화
  • 테스트 자동화를 CI 파이프라인에 포함시켜 PR 단계 품질 확인안정적인 배포 사이클 정착

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% 성능 개선
  • 모달 전환 시 이미지 깜빡임 제거로 사용자 경험 향상

🧠 배운 점

이미지 깜빡임 문제를 해결하면서 웹 성능 최적화에 대한 시각이 완전히 바뀌었습니다. 처음에는 단순히 이미지 로딩 문제로만 생각했는데 실제로는 캐시 정책CDN 설정이 핵심이었습니다. vercel.json 하나로 이렇게 극적인 변화가 생길 줄 몰랐습니다. 450ms에서 59ms로 로딩 시간이 줄어든 것도 놀랍지만 캐시 HIT율이 90% 이상으로 올라간 건 정말 인상적이었습니다. 이 경험을 통해 프론트엔드 개발에서 정적 자원 관리의 중요성을 체감했고 앞으로는 초기 설정 단계에서부터 캐시 전략을 고민해야겠다고 생각했습니다.

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

    📌 문제 배경

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

    🔍 원인 분석

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

    🛠 해결 과정

    1. IntersectionObserver + 사용자 행동 기반 라우트 사전 로드 구현
      • IntersectionObserver를 활용하여 카드가 뷰포트 100px 이내에 들어오면 해당 프로젝트 상세 경로를 `router.prefetch`로 사전 로드하도록 구현
      • 추가적으로 사용자가 프로젝트 카드에 마우스 오버(onMouseEnter)하거나 포커스(onFocus)할 때도 router.prefetch를 호출해 인터랙션 기반의 사전 로딩을 보완

    ✅ 결과

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

    🧠 배운 점

    단순히 클릭을 기다리던 기존 방식이 사용자에게 얼마나 큰 지연 시간으로 다가갔는지 체감할 수 있었습니다. 이번에 IntersectionObserver를 활용해 사용자의 시선이 머무를 만한 영역을 예측하고 리소스를 미리 로드하는 전략을 적용하면서 성능 최적화에 대한 시각이 완전히 바뀌었습니다. 개발자에게는 보이지 않는 수십 ms의 개선이 사용자에게는 '빠릿하다'와 '답답하다'의 차이를 만든다는 것을 숫자로 확인했습니다. 이제는 단순히 기능을 구현하는 데 그치지 않고 사용자의 다음 행동을 예측해 보이지 않는 곳에서 미리 준비해두는 습관을 들여야겠다고 다짐하게 되었습니다.

      MyPortfolio | Project