본 문서는 Flex 엔지니어링 인턴십 과제 제출을 위해 기존 Project Glim (next-gongtong) 프로젝트의 아키텍처를 분석하고 안정성, 성능, 그리고 데이터 일관성을 목표로 리팩토링한 결과입니다.
프로젝트는 Next.js 환경에서 구동됩니다.
⚙️ 환경 설정 및 실행 의존성 설치 후 개발 서버를 실행합니다.
npm install
npm run dev브라우저에서 http://localhost:3000 주소로 접속하여 3D 인터랙티브 공간을 바로 확인할 수 있습니다.
💡 백엔드 의존성 해결 (Fallback 구현)
이 프로젝트는 백엔드 API와의 연동을 전제로 설계되었으나, 현재 API 서버가 비활성화된 상태입니다.
저는 이 문제를 해결하기 위해 API 호출 실패 시 로컬에 저장된 더미 데이터(public/imageList.json)를 자동으로 불러와 3D 씬을 렌더링하는 대체 로직을 구현했습니다. 이 덕분에 백엔드 연결 상태에 관계없이 프로젝트의 핵심 기능을 언제든 안정적으로 시연하고 개발할 수 있습니다.
- 인터랙티브 3D 공간: Three.js와
react-three-fiber를 사용하여 책의 인용구와 이미지를 3차원 공간에 시각화한 '문장의 우주' 경험을 제공합니다. - 콘텐츠 포커싱: 특정 책을 클릭하면 카메라가 부드럽게 해당 콘텐츠로 이동(Focusing)하여 몰입도를 높이며, 다시 클릭하면 원래 시점으로 복귀합니다.
- 몰입형 UI: 3D 공간 경험에 집중할 수 있도록 초기 로딩 시 보였던 2D 그리드 UI를 제거하고 인터페이스를 개선했습니다.
이번 리팩토링은 주로 데이터 흐름의 일관성 확보와 성능 최적화에 중점을 두었습니다.
| 진단된 문제 | 해결책 | 설계 의도 (왜?) |
|---|---|---|
| 상태 불일치 및 중복 호출 | 경량 전역 상태 관리 라이브러리 Zustand를 도입했습니다. | Scene.tsx와 같은 형제 컴포넌트 간의 복잡한 상태 공유를 간소화하고, 모든 데이터 요청 로직을 **src/store/imageStore.ts**로 중앙화하여 **'단일 데이터 소스'**를 구축했습니다. 이를 통해 3D 객체가 뭉쳐 보이는 렌더링 버그를 해결하고, 불필요한 API 중복 호출을 제거했습니다. |
| UI/3D 경계 문제 | layout.tsx에서 3D 캔버스(Scene)와 2D UI(Header, children)를 분리된 레이어로 구성하는 구조를 유지했습니다. |
3D 배경은 유지하고 2D UI만 교체되는 효율적인 렌더링과 깔끔한 관심사 분리를 가능하게 합니다. (현재 2D 그리드 UI는 제거되어 page.tsx는 빈 상태입니다.) |
클라이언트는 직접 외부 API를 호출하는 대신, Next.js의 서버 환경에 위치한 src/app/api/quotes/route.ts (BFF) 만을 바라보도록 구현했습니다.
- 보안: 외부에 노출되어서는 안 될 Admin용 API 주소 및 복잡한 데이터 변환 로직을 서버 환경에 캡슐화했습니다.
- 효율성: 서버 환경에서 외부 API의 페이지네이션을 처리하고 클라이언트가 원하는 형태로 데이터를 미리 가공하여 전달함으로써, 클라이언트 측의 부담을 줄였습니다.
- 이슈:
Scene.tsx의 3D 객체들이frustumCulled={false}속성 때문에 화면 밖에 있어도 모두 렌더링되어 성능 저하가 우려되었습니다. - 조치: 해당 속성을 제거하여 Three.js의 기본 기능인 **절두체 컬링 (Frustum Culling)**이 활성화되도록 했습니다. 이를 통해 사용자에게 보이지 않는 객체의 렌더링 부하를 줄여 성능을 체감할 수 있을 만큼 향상시켰습니다.
사용되지 않던 HeroContent.tsx 컴포넌트, 이전 기능의 잔재였던 불필요한 훅 파일(예: useApiData.ts의 잔재), 그리고 중복되던 더미 데이터를 모두 제거하여 코드베이스를 깔끔하게 정리했습니다.
- 데이터 캐싱 전략 도입: 현재는
Zustand를 통해 상태 일관성을 확보했지만, 데이터 페칭 라이브러리(SWR또는React Query)를 추가로 도입하여 API 응답을 캐싱하고 자동 갱신함으로써 사용자 경험(UX)과 서버 부하 관리를 최적화하고 싶습니다. - 안정적인 데이터 관리 시스템 구축: 현재의 임시적인 폴백(
imageList.json)을 넘어, 백엔드 서버가 불안정하거나 비활성화될 때를 대비하여 Headless CMS와 같은 솔루션을 연결하여 콘텐츠를 관리하는 방안을 모색하고 싶습니다.