Skip to content

Latest commit

 

History

History
129 lines (86 loc) · 7.76 KB

File metadata and controls

129 lines (86 loc) · 7.76 KB

프로젝트 개요: Git Resource Viewer

1. 프로젝트 소개

Git Resource Viewer는 GitHub 레포지토리의 이미지 파일들을 보여주는 싱글 페이지 웹 앱입니다. Vercel을 통해 배포되며, 커스텀 가상 스크롤Web Worker 기법을 사용하여 레포지토리 내 모든 이미지를 효율적으로 탐색할 수 있도록 개발되었습니다.

2. 주요 기능

  • GitHub 레포지토리 이미지 조회
    사용자가 특정 GitHub 레포지토리의 URL을 입력하거나 예제 레포지토리를 선택하면, 해당 레포지토리에 포함된 이미지 파일을 불러옵니다. 기본 브랜치를 자동으로 감지하여 이미지 목록을 조회합니다.

  • URL 공유 기능
    React Router의 BrowserRouter를 활용한 라우팅을 적용하고, nuqs 라이브러리를 통해 필터링 설정을 쿼리 파라미터로 저장하여 URL 공유 시 동일한 화면을 재현할 수 있습니다.

  • 이미지 필터링
    필터링 기능을 통해 특정 문자열이 포함되거나 제외되는 이미지 파일만 표시합니다. (예: keyword -exclude 형식)

  • 이미지 ZIP 다운로드
    필터링된 모든 이미지를 ZIP 파일로 일괄 다운로드할 수 있습니다.

  • 이미지 뷰어
    이미지를 클릭하면 전체 화면 뷰어에서 확인할 수 있습니다. 키보드 화살표 키나 마우스 휠로 이미지 간 네비게이션이 가능하며, 개별 이미지 다운로드도 지원합니다.

  • Minecraft 애니메이션 지원
    Minecraft 리소스 팩의 .mcmeta 파일을 파싱하여 스프라이트 시트 애니메이션을 지원합니다. Canvas 기반 애니메이션 렌더링으로 게임 텍스처를 정확하게 재생합니다.

  • 커스텀 가상 스크롤
    react-virtualized 대신 직접 구현한 가상 스크롤 시스템을 사용하여 대량의 이미지 렌더링 성능을 최적화합니다. IntersectionObserver를 활용해 화면에 보이는 이미지들만 렌더링합니다.

  • GitHub API 요청 캐싱
    API 요청 횟수 제한 (Rate Limit)으로 인한 기능 중단을 방지하기 위해 IndexedDB와 localStorage를 활용한 하이브리드 캐싱 전략을 구현했습니다. ETag를 활용한 HTTP 304 응답 처리로 API 호출을 최소화합니다.

  • GitHub 개인 토큰 저장 지원
    사용자가 GitHub 개인 액세스 토큰을 입력할 수 있도록 하여, 인증된 요청을 통해 더 많은 API 요청을 수행하고 비공개 저장소에 접근할 수 있도록 지원합니다.

  • 사용자 설정 기능
    그리드 컬럼 수 조정(자동/수동), 픽셀레이트 렌더링 옵션, Minecraft 애니메이션 활성화/비활성화 등 사용자 맞춤 설정을 제공합니다.

  • 반응형 UI
    다양한 화면 크기에서 최적의 사용자 경험을 제공하도록 디자인되어 있습니다.

3. 기술 스택 및 선택 이유

  • 프론트엔드: React 19, TypeScript, Vite
    React 19의 Suspense와 Lazy Loading을 활용한 코드 스플리팅으로 초기 로딩 성능을 최적화하고, TypeScript를 통해 타입 안정성을 확보했습니다.

  • 스타일링: Tailwind CSS
    유틸리티 퍼스트 방식으로 빠르고 직관적인 스타일링을 제공하며, 클래스 기반 스타일링으로 코드 중복을 줄이고 가독성을 높입니다.

  • 상태 관리: Zustand
    가벼운 상태 관리 라이브러리로 불필요한 복잡성을 줄이고 성능을 최적화하며, 간단한 API 설계를 통해 코드의 직관성과 유지보수성을 높입니다.

  • URL 상태 관리: nuqs
    React Router와 통합되어 URL 쿼리 파라미터를 React 상태로 쉽게 관리할 수 있어 필터링 설정 공유 기능을 구현했습니다.

  • 컴포넌트 라이브러리: Radix UI (Shadcn 기반)
    접근성을 고려한 프리셋 컴포넌트를 활용하여 UI 개발 속도를 높이고, 디자인 일관성을 유지할 수 있습니다.

  • 데이터 캐싱: IndexedDB (idb-keyval)
    대용량의 캐시 저장을 위해 IndexedDB Storage를 사용합니다. 지원하지 않는 브라우저의 경우 localStorage를 폴백으로 활용하는 하이브리드 캐싱 시스템을 구현했습니다.

  • 라우팅: React Router (BrowserRouter)
    Vercel의 리다이렉트 설정을 통해 정적 사이트에서도 라우팅이 가능하도록 구현했습니다.

  • 성능 최적화: 커스텀 가상 스크롤 + Web Workers
    react-virtualized 대신 직접 구현한 가상 스크롤 시스템을 사용하여 번들 크기를 줄이고 스크롤 성능을 최적화했습니다. Web Worker를 활용하여 무거운 데이터 처리 작업을 메인 스레드에서 분리하여 브라우저 멈춤 현상을 방지했습니다.

  • 이미지 다운로드: jszip, file-saver
    여러 이미지를 ZIP 파일로 압축하여 다운로드할 수 있는 기능을 구현했습니다.

  • 애니메이션 렌더링: Canvas API
    Minecraft .mcmeta 파일을 파싱하여 Canvas를 활용한 스프라이트 시트 애니메이션을 구현했습니다.

  • 배포: Vercel
    Vercel을 통해 별도의 서버 관리 없이 정적 사이트로 배포합니다. GitHub와의 연동을 통해 커밋 시 자동 배포됩니다.

4. 문제 해결 사례

대량 이미지 렌더링 이슈

문제: 수천 개의 이미지를 렌더링할 때 브라우저 버벅임 발생
해결: 커스텀 가상 스크롤 시스템 구현

  • IntersectionObserver로 가시 영역 이미지만 렌더링하여 메모리 사용량 최적화
  • 동적 그리드 크기 계산으로 반응형 레이아웃 구현
  • overscan 영역 관리로 스크롤 시 끊김 없는 사용자 경험 제공

브라우저 멈춤 현상 개선

문제: 수천 개의 파일 목록 가공 처리 중 브라우저 멈춤 현상 발생 (최대 30초)
해결: Web Worker 기반 비동기 처리 시스템 구현

  • 추상 클래스 기반 Worker 시스템 설계로 재사용성 확보
  • Worker별 독립적 캐싱 및 에러 복구 메커니즘 구현
  • 메인 스레드와 Worker 간 효율적 통신 구조 설계

GitHub API 요청 제한 해결

문제: API 호출 횟수 시간 당 50회 제한으로 인한 서비스 중단 위험
해결: 다층적 캐싱 전략 및 제한 우회 로직 구현

  • ETag 기반 HTTP 304 응답 처리로 API 호출 최소화
  • IndexedDB를 주 저장소로 사용하고 localStorage를 폴백으로 활용하는 하이브리드 캐싱 시스템 구축
  • 캐싱 수단을 추상화하여 Worker 환경에서도 동일한 인터페이스로 접근 가능하도록 설계
  • API 실패 시 HTML 파싱을 통한 대체 데이터 수집 로직 구현

5. 성과 및 회고

기술적 성장

  • 브라우저 API를 활용한 성능 최적화 경험 획득
  • 타입 시스템 기반 안정적 코드베이스 설계 역량 향상
  • 대규모 데이터 처리를 위한 최적화 전략 수립 능력 배양
  • 한계 조건이 있는 외부 API를 효율적으로 활용하고, 이를 보완하는 클라이언트 전략 설계 능력 향상

아키텍처 설계 경험

  • Worker 기반 비동기 처리 아키텍처 설계
  • 다중 저장소 활용 캐싱 시스템 구현
  • 에러 복구 메커니즘이 포함된 안정적 시스템 설계
  • React 앱에서의 캐싱 전략과 상태 관리, 비동기 흐름 제어에 대한 실전 경험 획득

문제 해결 역량

  • 대량 데이터의 정제 작업까지도 비동기 처리가 필요하다는 것을 배울 수 있었습니다
  • 다층적 캐싱 전략을 통한 API 한계 극복 방안 수립
  • 성능과 사용자 경험을 모두 고려한 최적화 전략 구현
  • Worker 환경과 메인 스레드 간 효율적인 통신 구조 설계 경험