Team Monument Gallery의 설계나 기술적인 고민들을 다룹니다.

상태관리 라이브러리 zustand 를 이용한 토스트 구현하기

✨  커스텀 Suspender 구현으로 React Suspense 활용하기

🤟🏻 WebGL 3D프로젝트에서 무한 페이지네이션 구현하기

텍스트 압축(gzip)을 통한 웹 사이트 성능 개선하기

SSE를 이용한 로딩 프로그레스바 구현기

인덱스를 활용한 효율적인 쿼리

Promise.all을 이용한 Async&Non-blocking 구현

셰이더 프로그래밍을 이용한 사진 파편 구현기

셰이더 프로그래밍을 이용한 사진 파편 구현기

<aside> ✨ 사진 파편 애니메이션을 구현하기 위해 각 삼각형을 메시로 관리하여 애니메이션을 구현하기에는 최소 5000개, 최대 20만 개의 드로우 콜로 인한 성능저하 문제가 존재합니다. (5000개의 메시가 한 화면에 그려지면 30FPS로 프레임 드랍이 발생함)

사진 파편의 모든 삼각형을 하나의 지오메트리로 관리한 뒤, 정점을 움직이는 방식으로 드로우 콜을 줄였으며, 지오메트리를 애니메이션이 일어나는 동안 1초에 60번씩 움직이는 데에는 프레임당 20ms로 애니메이션 도중 프레임 드랍이 생기기 때문에, 애니메이션 재생 도중에는 셰이더 프로그래밍을 이용하여 GPU로 버텍스를 계산하고, 애니메이션의 시작과 끝부분만 CPU로 버텍스 위치를 실제 보이는 위치와 동기화하는 방식으로 구현했습니다.

100x100 사진 파편이 6개 이상 보여져도 60FPS가 유지되는 안정적인 퍼포먼스를 얻었습니다.

</aside>

메모리 사용 절감을 통한 초기 렌더링 최적화

메모리 사용 절감을 통한 초기 렌더링 최적화

<aside> 📟 많은 양의 섬이 존재하는 갤러리 페이지를 렌더링할 때, 자바스크립트 코드를 실행하는 시간이 오래 걸려서 Lighthouse 점수가 매우 떨어지는 문제가 존재했습니다.

해당 문제를 해결하기 위해 초기 렌더링 요소를 분석한 결과, 사진 파편의 초기 렌더링 속도가 개당 100ms 정도로 느리며, 메모리 사용량이 많다는 것을 알게 되었고, 잦은 배열의 생성이 버려지는 메모리를 유발해 가비지 컬렉션을 유도하는 것을 원인으로 분석했습니다.

해당 문제는 배열을 스프레드 연산자로 합치는 방식을 제외하여 하나의 큰 배열에 원소를 추가하는 방식으로 변경하여 해결했으며, 사진 파편 개당 100ms에서 25ms로 초기 렌더링를 4배 향상시키는 결과를 얻을 수 있었습니다.

</aside>

원활한 Dev 서버 개발환경 구축 노력

원활한 Dev 서버 개발환경 구축 노력

<aside> 🎛️ 배포 환경에서는 페이지 라우팅 서버와 API 서버를 분리하지 않고 서버를 구축하였으나, 개발 환경에서는 클라이언트 서버와 API 서버가 분리되어 있어서, 배포시 개발 과정에 최적화된 클라이언트 코드를 고쳐야 하거나, 프로덕션 환경과 다른 동작으로 페이지가 이동되고 통신되어서 개발상 혼란을 주는 등 문제가 존재했습니다.

최대한 프로덕션 환경과 유사한 환경에서 개발을 진행하기 위해, 서버에서 클라이언트 html 파일을 보내 주는 것을 모사하여, 개발 모드일 때 Node.js 서버에서 페이지를 요청하면 Vite 서버로 프록싱을 하는 것을 구현하였습니다.

</aside>

<aside> 🎛️ Vite Dev 서버는 싱글 페이지 기반으로 페이지를 서빙하여, 정확한 애셋 경로가 아니면 모두 index.html를 호출하지만, 실제 배포 환경에서는 /create, /gallery/(id)/(history) 등 정확한 애셋 경로가 아닌 URL을 요청해서 html을 응답으로 받아야 합니다.

최대한 프로덕션 환경과 유사한 환경에서 개발을 진행하기 위해, Vite dev router 플러그인을 제작하여, 특정 패스의 패턴과 일치하면 해당하는 html을 보내주는 플러그인을 만들어서 프로덕션 환경과 동일한 라우팅을 구현하였습니다.

그 결과 클라이언트 코드에서 개발 코드와 배포 코드를 분리하지 않고 배포 코드 형식으로 작성할 수 있어서 추가적인 부담을 덜었으며, Vite Dev Server 단독으로 서버를 띄워도 배포 환경과 동일한 라우팅을 할 수 있어서 클라이언트 코드만 손 보면 되는 기능을 테스트할 때에도 Node.js 서버를 띄우지 않아도 되어 빠른 작업 속도를 보장할 수 있었습니다.

</aside>