

하품(HAPOOM) 은 하늘의 순간을 사진에 담아 나누는 새로운 경험의 소셜미디어 플랫폼입니다. 이 플랫폼은 인스타그램, 트위터, 페이스북과 같은 사진을 공유하는 소셜미디어에서 아이디어를 착안하여 시작되었습니다.
목적 및 배경
우리는 다양한 상황 속에서, 때로는 아무 생각 없을 때, 슬플 때, 기쁠 때, 또는 하늘이 그저 예쁠 때 하늘을 찍곤 합니다. 그러나 이런 순간의 사진을 공유할 목적이 명확하지 않은 경우가 많습니다. 하품은 이러한 간절한 감정들을 담은 사진들이 그저 갤러리에 머무는 것이 아니라, 다른 이들과 공유하며 더 큰 의미를 지닐 수 있도록 만들어진 플랫폼입니다.
- 2023년 7월 28일 ~ 9월 8일 (6주)
| 감정 공유 |
사용자는 하늘의 사진을 찍어 업로드하며, 그 순간의 감정을 다른 사용자들과 공유할 수 있습니다. 이는 단순한 사진 공유가 아닌, 그 순간의 감정과 연결된 진정한 소통이 가능하게 합니다. |
| 다양한 태깅 기능 |
업로드한 사진에는 음악, 장소, 하고 싶은 말, 해시태그를 추가할 수 있어, 사진과 함께 그 순간의 분위기를 더욱 선명하게 전달할 수 있습니다. |
| 커뮤니티 형성 |
하품은 사용자들이 자신만의 하늘을 공유하며 서로의 감정을 이해하고 공감할 수 있는 따뜻한 커뮤니티를 형성하는 것을 목표로 합니다. |

| 사용 기술 |
결정 사유 |
| styled-components |
CSS IN JS로 동적인 스타일링이 가능하며, 재사용 컴포넌트를 구축하는데에 유리함. 또, 각 요소마다 고유한 클래스 이름을 부여할 수 있으므로 클래스명 중복으로 인한 스타일링 겹침 문제를 해결하는데에 용이함. |
| Vercel |
Github를 통해 자동 빌드 및 배포가 가능한 것에 더불어, 배포 최적화로 개발 프로세스가 간단해짐. |
| Axios |
내장 라이브러리의 다양성과 axios interceptor/instance 사용으로 관리 및 유지보수의 용이성에 따라 선택함. |
| react-query |
서버와 통신을 주고 받는 부분이 많은 본 프로젝트 특성상 서버 상태 관리에 가장 최적화 된 라이브러리가 필요했으므로 선택을 결정함. 특히, infiniteQuery는 게시물을 미리 prefetch 할 수 있고 데이터 캐싱으로 UX 개선과 로직의 효율적인 구성을 지원한다는 장점이 있었음. 쿼리키를 사용해 데이터를 정확히 구분하고 필요한 만큼만 리렌더링하는 구조를 구축하는데에 용이하게 사용되었음 |
| Redux |
유저 정보와 테마 등 전역 상태 관리를 위해 채택함. 최소한의 서버상태 관리만을 하도록 리액트 쿼리와 데이터를 구분하여 관리함. |
| Next.js |
react를 완전체 프레임워크로 사용하기 위해 선택함. 이미지와 스크립트, 링크 등의 강력한 내장 라이브러리를 통해 효율적으로 최적화를 진행하고, 각 페이지와 컴포넌트에 따라 csr, ssr, ssg를 취사선택하여 효율적인 서비스를 제공하는데에 용이함. 또한, 코드스플리팅을 통해 각 페이지의 초기 렌더링 JS 양을 줄일 수 있음. |
| Typescript |
런타임에러를 컴파일 시점에 잡아낼 수 있어 안정적인 코드 운용이 가능함. 명확한 타입 정보를 제공하여 가독성이 좋기에 프로젝트 규모의 크기를 불문하고 유지보수가 용이함. 또한, JS 라이브러리나 프레임워크를 그대로 사용할 수 있다는 점이 강점이었음. |
-
| 피드 페이지에서 인피티니 스크롤을 적용함. 그러나 다음 게시물을 불러올 때마다 전체 게시물이 새롭게 렌더링되고, 스크롤이 자동으로 페이지 최상단으로 이동하는 문제가 발생함. |
| 오류 발생 경로 |
메인의 FEED 페이지 |
| 오류 해결 시도 |
해결을 위해 컴포넌트의 메모이제이션을 시도하였고, 리렌더링을 유발할 가능성이 있는 코드의 일부를 주석처리함. 또한, 인피니티 스크롤의 로직을 변경했음. |
| 오류 해결 방법 |
React Query의 ‘useInfiniteQuery’를 사용하여 데이터를 가져옴. 기존 로직에서는 state 변수에 가져온 게시물을 추가하여 렌더링을 하지만, 이번에는 지역 변수에 데이터를 push하여 지역 변수로 직접 렌더링했음. 이 방식으로 전체 페이지의 리렌더링을 막을 수 있었음. |
-
| 파일 업로드 및 수정 페이지에 접속할 때 성능이 눈에 띄게 저하되는 문제가 있었음. |
| 오류 발생 경로 |
post/write |
| 오류 해결 시도 |
성능 향상을 위해 로딩이 길 수 있는 컴포넌트에 대해 다이나믹 선언을 통한 레이지 로딩과 코드 스플리팅을 적용하였음. 또한, 컴포넌트 메모이제이션도 추가함. |
| 오류 해결 방법 |
글쓰기와 글수정의 로직이 유사하여 재사용을 위해 파일 업로드 컴포넌트들이 blob/file 형태로 파일을 다루도록 설정되어 있었음. 여기에서 글을 수정하기 위해 기존 데이터에서 URL을 refetch하여 blob/file로 변환하는 과정이 있었는데, 이 과정을 완전히 제거하고 리펙토링함. 이를 통해 파일을 URL 만으로 다루는 컴포넌트를 적용하게 됨으로써 성능 저하 문제가 해결됨. |
-
| Next.js의 SSR(서버사이드 렌더링)을 사용하는 모든 페이지에 접속할 때, 비정상적으로 성능이 하락하는 문제가 발생함. |
| 오류 발생 경로 |
SSR이 적용 된 모든 페이지 |
| 오류 해결 시도 |
라이트하우스와 웹 브라우저의 개발자 도구를 활용하여 성능 지표를 체크하고 원인을 규명하려고 노력하였음. |
| 오류 해결 방법 |
배포 이후부터 이 문제가 지속적으로 발생하고 있었다는 점에 주목하였음. 추가 분석 결과, 서버의 스펙이 t2.micro로 비교적 낮아 SSR 성능이 떨어질 수 밖에 없다는 점을 알아냄. 따라서, SSR이 반드시 필요하지 않은 페이지는 CSR (클라이언트사이드 렌더링)을 사용하도록 리펙토링하여 성능을 크게 개선함. |
-
| 유투브 API의 검색 quote 하루 제한량이 너무 낮아 기존 적용하던 기획 및 개발 내역을 사용하기 어려워짐 |
| 오류 발생 경로 |
components/Write/youtubeSearch |
| 오류 해결 시도 |
검색 요청을 최적화 하기 위해 디바운스 기능을 적용하고, 유투브 API의 요청량을 줄일 방법을 다양하게 조사함. 그러나 Youtube Data API v3은 최소 요청량이 제한되어 있어, 개인당 하루 100~150회 정도의 검색만 가능하다는 것을 알게 됨. |
| 오류 해결 방법 |
팀원 7명 모두가 각자 API 키를 신청하였고, 이 키들을 모두 .env 파일에 저장하여 배열로 관리하였음. 하나의 API키의 사용량이 끝나면, 다음 API키로 자동으로 전환되도록 설정하였음. 이렇게하여 하루 검색량을 7배로 늘리고, 서비스를 정상적으로 운영할 수 있도록 함. |
-
| iOS 유저들이 사진 업로드 기능을 사용하는 과정에서 불편을 겪는 문제가 있었음 |
| 오류 발생 경로 |
사진 업로드 |
| 오류 해결 시도 |
iOS 환경과 다른 플랫폼 (안드로이드, 윈도우 등) 사이의 차이점을 조사하고, 이와 관련된 다양한 레퍼런스를 찾아보았음. 그 결과 iOS 14버전 이후로 서드파티 쿠키에 대한 제한이 강화된 것을 알 수 있었음. 이로 인해, 원래 다른 디바이스에서는 문제 없이 작동하던 ‘sameSite: None’, ‘secure: true’ 설정을 가진 쿠키가 iOS에서는 전달되지 않는 문제가 발생하고 있었다는 사실을 알게됨. |
| 오류 해결 방법 |
글쓰기 로직에서 쿠키를 필요로 하지 않도록 변경하여 업로드 문제를 해결함. |