- 크리스마스에 사람들끼리 속마음을 주고받으면 어떨까❓
- 롤링페이퍼처럼 여러사람이 한 곳에 메시지를 작성 하는 아이디어📄
- 반응형 3D로 입체감있는 스노우볼 제작🔮
장식을 클릭하면 메세지를 확인 할 수 있어요 💝
스노우볼을 클릭하면 내부로 들어가서 장식 클릭이 가능해집니다.
장식을 클릭하면 메세지가 보여요.
읽지 않은 메세지는 ❗ 표시가 떠있어요.
장식과 색깔을 선택해 개성있는 스노우 볼을 만들고 공유해 보세요 🔮
원하는 장식과 색깔을 선택 할 수 있어요.
스노우볼의 이름을 직접 정해줄 수 있어요.
링크를 마음을 전달 받고 싶은 사람들에게 공유해요.
이쁜 장식을 만들어 따뜻한 말을 담은 메세지를 남겨보세요 ! 💌
공유 받은 링크를 통해 스노우볼 주인의 장식을 구경해요.
스노우볼에 들어갈 장식을 직접 선택해요.
전하고 싶은 마음을 메세지에 담아 장식과 함께 전달해요.
J034 | J064 | J082 | J074 | J160 |
---|---|---|---|---|
김찬우 | 서민아 | 오승엽 | 송현우 | 최진수 |
Front-End | Front-End | Front-End | Back-End | Back-End |
잘 부탁드려요 연말 -낭만사냥꾼- |
나도 3D사이트,, 할 수 있다,,🔥 |
안녕하세요 저는 오승엽입니다 누군가는 해야하잖아🤯 |
Back-End | 백린이 최진수입니다 |
분류 | 기술 스택 |
---|---|
공통 |
|
프론트엔드 |
|
백엔드 |
|
패키지 매니저 |
|
배포 |
|
협업 |
이번 프로젝트를 통해 가장 중점적으로 생각한 부분은 실제 사용자들이 사용할 서비스를 만들자
였습니다.
프론트 엔드 팀원 모두 React
에 익숙하지 못했고, 어려운 기술적인 부분보다는 기초적인 부분에 충실하게 학습하여 구현을 해나가는것을 목표로 삼았습니다.
개발환경을 PC 환경에서 크롬으로 진행하며 반응형으로 프로젝트를 진행하였습니다.
간단한 프로토타입을 완성 후, 빠른 배포를 통해 여러 기기에서의 UI를 확인해보고 성능을 테스트 해보았습니다.
그 와중, 3D 모델 렌더링 과정에서의 최적화 문제를 발견하였고, Three.js
의 모델링의 Mesh
를 조절하고 rAF 기반인 useFrame
을 여러개를 사용하지 않고 하나의 컴포넌트로 묶어 최적화를 진행하여 갤럭시 S10 기준 GPU 를 98% 에서 70% 가량으로 렌더링 성능을 낮추었습니다.
다음으로, 아이폰 IOS
17 버전 이후로 사파리 어플리케이션에서 문제가 나타나게 되었고, 기존 화면의 크기를 자동으로 계산해주는 100vh
에서 직접 렌더링 되는 화면을 계산해 카카오톡, 인스타그램과 같은 임베드 웹까지 적절하게 렌더링 될수 있도록 수정하였습니다.
다음으로 매번 배포해서 모바일 환경을 실시간으로 CSS 를 디버깅하기에 어려움이 있어 여러 방법을 도입하였습니다.
- 구글 크롬 스마트폰 모바일 개발자 도구 (안드로이드)
- 유료 프로그램
- vite 로컬 호스트 연결
이렇게 세가지 방법을 찾아보았고 그중에 가장 접근성이 좋은 vite 로컬 호스트 연결을 선택하였습니다.
vite.config.ts
의 host를 설정해 같은 네트워크를 공유하여 실시간으로 모바일 환경을 볼 수 있었습니다.
SSOCK 팀 프론트엔드에서 설계한 컴포넌트 구조의 간략한 시각화는 다음과 같습니다.
크게 Three.js
로 렌더링한 Canvas 컴포넌트와 UI 를 구분지어 설계하였습니다.
3D 모델을 렌더링 하는것은 성능에 큰 영향이 있었고, 프로젝트 기준 애니메이션 효과가 많이 들어가 리렌더링을 하게 된다면 애니메이션 효과들이 처음부터 시작되어 (위 소개 GIF 예시로 장식이 다시 떨어지는 문제) 사용자 경험에 부정적 영향을 줄 수 있었습니다.
따라서 리렌더링에 사용되는 useState
훅을 UI 내부에서 사용하려 시도하였고, 그로인해 Canvas 컴포넌트와의 depth
차이에 대해 깊게 고민하고 사용하게 되었습니다.
또한 기존 React 에 기본기에 충실하기 위해 다른 상태관리 라이브러리를 사용하지 않고 useContext
훅을 사용해 상태관리를 하였습니다.
각 라우팅된 페이지들의 공통적으로 사용되는 데이터들을 정의해주고 Provider
로 하위 컴포넌트들을 감싸 Canvas 와 UI 모두 동일한 데이터를 제공하였습니다.
그로인해 Canvas로 렌더링된 장식 모델에 대한 이벤트처리를 UI 에서 처리할수 있어 Canvas 를 리렌더링 하지 않고 정상적으로 메세지를 띄울수 있었습니다.
하지만 반대의 경우도 고려를 해야할 필요가 생기게 되어 문제가 되었습니다.
읽지않은 메세지의 경우 Canvas 에서 3D 모델 ❗ 로 렌더링 하였는데, 장식을 클릭하였을때 UI 와 Canvas 모두 리렌더링을 동시에 해야 하는 경우가 생기게 되었고, 메세지를 읽을 때마다 3D 모델이 리렌더링 되어 다시 떨어지게 되었습니다.
이때 컴포넌트의 props
를 비교해 이전 값과 같으면 리렌더링을 하지 않는 React.memo
고차 컴포넌트를 사용하여 해결하였습니다.
React.memo 적용 전 | React.memo 적용 후 |
---|---|
네이버 부스트캠프 챌린지때 읽었던 함께 자라기
책을 읽고 애자일 방법론에 대해 알게 되었고, 팀원들과 함께 이번 프로젝트에 적용해보기로 결정하였습니다.
3주차 부터 프로토타입이 나오게 되면서 개발자들의 입장과 사용자들의 입장 차이가 상당히 다르다는 것을 경험하게 되었습니다.
피드백 수용한 사용자 편의성 개선
피드백 수용 전 | 피드백 수용 후 |
---|---|
매주 여러 사용자들에게 피드백을 받으며 프로젝트를 보완하고 수정하였습니다.
저희 백엔드 팀원이 이번 프로젝트를 통해 가장 중점적으로 생각한 부분은 많은 이용자들을 고려한 서버 구성 및 효율적인 설계입니다
백엔드 팀원 모두 실제 배포 및 Nest.js가 처음이었고, 새로운 기술들을 도입하기 보다는 기존에 많이 사용하는 기술 스택을 더 깊이있게 공부하며 사용하는 것을 목표로 잡았습니다
NCP를 이용하여 실제 사용되는 인프라 구조와 비슷하게 백엔드 인프라를 구축하는것이 저희의 목표였습니다.
VPC안에 Nginx를 실행하는 웹서버를 공개 서브넷에 빼주고 WAS서버와 데이터베이스 서버를 비공개 서브넷에 넣어주었습니다.
비공개 서브넷을 사용해서 백엔드 서버와 데이터베이스의 외부접근을 막아줌으로 1차 보호를 해주었습니다.
CI/CD를 구성하는 과정에서 백엔드서버가 비공개 서브넷에 포함되어있어 백엔드 서버에 배포가 되지 않는 에러가 발생했습니다. 처음에는 VPC를 완전히 이해하지 못한 상황이라 해당 에러가 뜨는 이유를 찾지 못했습니다. 면밀한 검사 후 문제를 찾았고 백엔드 서버의 배포를 위해서 NAT 게이트웨이를 추가해줘서 외부에서의 incoming 통신은 차단하지만 백엔드서버에서의 outgoing 통신은 열어주어서 배포를 할 수 있었습니다.
유사한 다른 프로젝트를 참고하니, DDOS 공격으로 서버에 과부하가 걸리거나 예상치 못한 비용이 나오는 등의 문제가 있었습니다. 저희는 이를 예방하기 위해 ip별로 rate-limiting을 적용하여 요청이 비정상적으로 몰리는 ip를 차단했습니다
TypeORM을 사용하다보니 편리한 내장 함수에 의존하게 되어 실제로 쿼리가 어떻게 전송되고 설계되는 지 명확하지가 않았습니다. 그래서 저희는 쿼리 로그를 기록하며 필요하다면 rawQuery를 설계하여 서비스 로직을 구성했습니다.
더 자세한 기록은 노션과 위키를 확인해주세요.