React Native에 CodePush 도입기

React Native 기반 앱 프로젝트를 운영하면서, Store 심사 지연으로 인해 Hotfix 배포나 간단한 UI 수정조차 수일 이상 소요되는 일이 잦았습니다. 특히, 사용자(근로자)에게 주일 마다 피드백을 받아오는 상황에서 잦은 빈도로 업데이트되던 서비스였기 때문에, 이런 병목은 전체 업데이트 일정에 큰 영향을 끼쳤습니다. 이러한 문제를 해결하기 위해 CodePush 기반의 무중단 배포 환경을 구축했습니다. 왜 CodePush를 도입했는가 Microsoft에서 제공하는 CodePush는 React Native 앱의 JS 번들만 OTA(Over-the-Air) 방식으로 배포할 수 있도록 해주는 서비스입니다. 앱을 재설치하거나 스토어 심사를 거치지 않고도 즉각적인 업데이트가 가능한 구조입니다. ...

January 20, 2024

Next.js에서의 styled-components SSR 이슈와 해결

Next.js 프로젝트(v12)에서 styled-components를 적용하며 발생한 스타일 FOUC(Flash of Unstyled Content) 문제와 이를 해결한 과정을 정리했습니다. 문제 상황: SSR 환경에서의 스타일 미적용 Next.js는 기본적으로 서버 사이드 렌더링(SSR) 을 지원하며, 초기 페이지 로드 시 HTML을 미리 생성해 클라이언트에 전달합니다. 프로젝트 초기에 아래와 같은 문제가 발생했습니다: 새로고침 시 스타일이 적용되지 않은 HTML이 먼저 렌더링됨 이후 JS가 로드되면서 styled-components 스타일이 적용됨 사용자 입장에서 순간적으로 깨진 UI가 보이는 경험을 하게 됨 이는 흔히 말하는 FOUC (Flash of Unstyled Content) 플리커 현상으로, SSR 환경에서 styled-components를 사용할 때 자주 발생하는 이슈입니다. ...

July 23, 2023

Context API -> Recoil 성능 개선 과정

이전 글에서 클라이언트 상태와 서버 상태를 분리하는 과정에서 Context API 대신 Recoil을 도입하게 된 이유를 정리한 바 있습니다. 이번 글에서는 해당 구조가 실제 프로젝트에서 어떻게 적용되었는지, 그리고 Recoil을 사용함으로써 성능 측면에서 어떤 개선 효과가 있었는지를 자세히 공유하려고 합니다. 왜 Recoil이 필요했는가 이전 글에서 언급했듯이 처음에는 Context API만으로도 충분해 보였습니다. 작은 단위의 상태들을 중앙에서 관리하고, 빠르게 구조화할 수 있었기 때문이다. 하지만 프로젝트가 커지고 기능이 쌓이면서, Context를 사용하는 컴포넌트가 많아지고, 하나의 값 변경에도 여러 곳에서 렌더링이 발생하기 시작했다. ...

May 28, 2023

해외 사용자 대상 WebRTC 연결, 어떻게 진단했을까?

연결 단계에서 발견된 간헐적 연결 문제 WebRTC는 RTCPeerConnection과 ICE 프로토콜을 통해 두 클라이언트 간 최적 경로를 탐색한다. const peerConnection = new RTCPeerConnection({ iceServers: [{ urls: "example.google.com:19302" }], }); peerConnection.onicecandidate = (event) => { if (event.candidate) { socket.emit("ice-candidate", event.candidate); } }; peerConnection .createOffer() .then((offer) => peerConnection.setLocalDescription(offer)) .then(() => { socket.emit("offer", peerConnection.localDescription); }); 해외 네트워크 환경을 사용하는 사용자들의 연결 기능에서 다음과 같은 현상이 간헐적으로 발생했다: 영상이 연결되지 않거나 상대가 보이지 않음 상태 동기화나 메시지 수신이 실패함 네트워크 문제인지 브라우저 문제인지 식별하기 어려움 사용자 입장에서는 연결 상태에 대한 명확한 피드백이 없어 혼란을 느낌 📌 VPN 사용 환경에서의 연결 실패 또한 일부 사용자들이 VPN을 활성화한 상태에서 접속하는 경우, WebRTC 연결이 실패하는 이슈가 존재했습니다. ...

May 3, 2023

Context API 대신 React Query를 선택한 이유

이전 글에서 Recoil 활용해 클라이언트 상태를 정리했던 이야기를 남긴 적이 있다. 이번에는 같은 프로젝트 내에서 서버 상태를 다루는 방식에 대해 정리해보려 한다. Context API를 빠르게 선택했던 이유 처음 프로젝트를 시작할 때는 아주 간단한 요구사항만 있었기 때문에, 굳이 무거운 상태 관리 라이브러리를 도입하지 않고 Context API만으로 충분하다고 판단했다. 속도를 중시한 결정이었다. 실제로 빠르게 결과물을 만들 수 있었고, 배포도 문제없이 진행됐다. 하지만 이후 사업이 확장되며 기능이 하나씩 추가되기 시작했고, 그때부터 context 구조가 무겁게 느껴지기 시작했다. 추가되는 context마다 리렌더링 범위가 넓어졌고, UI 단위에서만 필요한 데이터까지 전역에 얹히는 구조가 되었다. ...

April 28, 2023