Gu Doyoon
  • Next.js
  • TypeScript
  • Framer Motion

Dev Portfolio

Next js 기반 포트폴리오

📅 2025.01 - 2025.02 (진행 중)👥 1명 (개인 프로젝트)🛠 프론트엔드 개발

트러블 슈팅

확장 불가능한 Flat 컴포넌트 구조의 한계 극복
자세히 보기
문제 상황

초기 트러블 슈팅 컴포넌트는 모든 데이터를 하나의 Props 객체로 전달받는 Flat한 구조였습니다. 하지만 요구사항이 늘어남에 따라 유지보수 지옥에 빠졌습니다.

// Before: 모든 케이스를 하나의 Props로 처리 <TroubleShooting title="제목" code={codeSnippet} videoSrc={...} />
해결 과정 (Compound Pattern)

컴포넌트의 제어권을 부모에게 넘겨주는 Compound Component 패턴을 도입하여 구조를 전면 리팩터링했습니다.

// After: 필요한 요소만 선택적으로 조합 <ProjectDetail> <ProjectDetail.Header>제목</ProjectDetail.Header> <ProjectDetail.Body> <ProjectDetail.Section title="문제">...</ProjectDetail.Section> <ProjectDetail.Code>{code}</ProjectDetail.Code> </ProjectDetail.Body> </ProjectDetail>
결과 요약
새로운 UI 요구사항 발생 시 기존 코드 수정 없이 컴포넌트 조합만으로 대응 가능한 유연한 구조 구축
뒤로가기 시 스크롤 위치 소실 문제 해결
문제 상황

페이지 이동 후 뒤로가기를 했을 때, 브라우저의 기본 스크롤 복원 동작이 완벽하지 않은 문제가 있었습니다.

해결 과정

Session StorageHistory API를 활용한 커스텀 훅 useScrollRestoration을 구현했습니다.

// useScrollRestoration.tsx useIsomorphicLayoutEffect(() => { if ('scrollRestoration' in window.history) { window.history.scrollRestoration = 'manual'; } }, []);
결과 요약
페이지 이동 간 정확한 스크롤 위치 복원으로 끊김 없는 탐색 경험 제공 및 오픈 소스 기여

성능 개선

In-View 감지를 통한 이미지 프리로딩 및 UX 개선
도입 배경

기존에는 상세 화면 진입 시 이미지를 요청하여 로딩 딜레이가 발생했습니다. 초기에는 Hover 방식으로 시도했으나, 모바일 환경(터치 인터페이스) 에서는 Hover 가 동작하지 않아 최적화 효과를 볼 수 없는 한계가 있었습니다.

구현 내용

IntersectionObserver 기반의 컴포넌트를 구현하여 In-View 의 프리로딩 시스템을 구축했습니다.

  1. Intersection Observer를 활용해 사용자가 해당 위치에 접근할 때 이미지를 백그라운드에서 미리 요청합니다.
  2. new Image() API와 decoding="async" 속성을 사용하여 DOM 렌더링 비용 없이 브라우저 캐시에만 이미지를 적재합니다.
const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting) { // DOM 렌더링 없이 브라우저 캐시에만 적재 const img = new Image(); img.decoding = 'async'; // 메인 스레드 블로킹 방지 img.src = src; observer.disconnect(); } }, { rootMargin: '200px' } // 뷰포트 진입 전 미리 로딩 );
성능 측정 (제한 없음 환경)
주요 성과 지표
클릭 후 로딩 시간
2,000ms1,000ms2배이상 감소
결과 요약
데스크톱 및 모바일 환경 모두에서 사용자 로딩시간 0초로 감소 및 CLS 제거