Pokemon Dogam
React + TypeScript + GraphQL 기반의 포켓몬 도감 웹 서비스. MobX 상태 관리, react-virtuoso 가상화 렌더링, Prisma ORM, Docusaurus 문서 사이트 운영까지 포함한 풀스택 프로젝트.
프로젝트 소개
- 제작 인원: 1명 (개발, 디자인)
- 제작 기간: 2022.12 — 2023.04
새로운 기술을 배우기보다, 이미 사용하고 있던 기술들의 숙련도를 끌어올리기 위해 시작한 프로젝트입니다. 기존 REST API 대신 GraphQL을 도입해 클라이언트-서버 간 데이터 통신을 경험했고, 실제 사용자를 상정한 배포·문서화·피드백 수집까지 운영형 프로젝트로 확장했습니다.
포켓몬이라는 주제는 넓은 인지도를 가지고 있어 실제 사용자층을 확보하기 좋았고, 닌텐도 스위치와 함께 사용하기 편하도록 모바일 최적화 UI를 우선으로 설계했습니다.
주요 구현
GraphQL 데이터 통신
기존에 익숙했던 axios/REST 방식 대신 GraphQL을 선택한 이유는 포켓몬 데이터의 특성 때문입니다. 리스트에서는 이름·번호·타입 정도만 필요하고, 상세 페이지에서는 진화 정보·강점·약점까지 필요한데, REST로는 불필요한 데이터까지 함께 받아야 했습니다. GraphQL을 통해 각 화면에서 정확히 필요한 필드만 요청하는 구조로 설계했습니다.
필터링 & 검색 최적화
- MobX 상태 관리: 타입, 세대, 메가진화, 전설 여부 등 복합 필터 조건을 MobX Store로 관리하여, 조건 변경 시 즉시 결과에 반영되도록 구현
- Debounce Hook 직접 구현: 검색어 입력 중에는 API를 호출하지 않고, 입력이 끝난 뒤 한 번만 검색을 실행하는 debounce 훅을 직접 제작하여 불필요한 요청을 절감
렌더링 성능 최적화
메인 화면에서 1,000개 이상의 포켓몬 카드를 보여주어야 했습니다. 카드 안에 이미지와 여러 컴포넌트가 있어 모든 데이터를 한 번에 렌더링하면 심각한 성능 저하가 발생했습니다. react-virtuoso 라이브러리를 도입해 사용자의 뷰포트 영역에 보이는 카드만 렌더링하는 가상화 방식을 적용했고, lazy loading을 함께 사용하여 초기 로딩 시간을 크게 단축했습니다. 이 최적화 과정은 기술 블로그에도 정리하여 공유했습니다.
상세 페이지
리스트 조회뿐만 아니라 각 포켓몬의 상세 정보(타입 상성, 진화 단계, 강점/약점)와 연관된 다른 포켓몬까지 탐색할 수 있는 상세 페이지를 구성했습니다. 포켓몬 캐릭터에 맞는 아기자기한 웹 폰트와 배경을 적용하여 전 연령대가 거부감 없이 이용할 수 있도록 UI를 설계했습니다.
문서화 & 운영
- Docusaurus 문서 사이트: 업데이트 내역, 이용 방법, 기술 이슈 해결 과정을 별도 블로그 형식 문서 페이지로 운영
- 커뮤니티 배포: 온라인 커뮤니티에 직접 홍보하고, 사용자 피드백을 수집하여 이슈 개선과 기능 업데이트를 반복
- 공식 이미지 사용: 2차 창작물이 아닌 공식 이미지를 활용하여 정보의 신뢰성을 확보
배운 점
- GraphQL의 쿼리 설계와 스키마 정의를 통해 클라이언트 주도의 데이터 요청 패턴을 이해했습니다.
- 대량 데이터의 렌더링 최적화(lazy loading, 가상화)를 직접 적용하며 성능 병목을 해결하는 경험을 쌓았습니다.
- 단순 개발을 넘어 문서화, 배포, 사용자 피드백 루프까지 “운영 가능한 제품”을 만드는 관점을 갖게 되었습니다.
지금 돌아보면
당시에는 debounce hook을 직접 구현하고 react-virtuoso로 렌더링을 최적화하는 것에 만족했지만, 지금이라면 비즈니스 로직과 UI 로직을 더 명확히 분리하고 서버 사이드 캐싱 전략을 추가해 네트워크 요청 자체를 줄이는 방향으로 접근할 것입니다. 이 프로젝트에서 경험한 문서화·운영·피드백 수집 사이클은, 이후 실무에서 CMS 구축과 서비스 안정성 관리에 직접적으로 이어졌습니다.