상품 상세 React 전환기

Hyungjoo Kwon
29CM TEAM
Published in
9 min readSep 26, 2022

안녕하세요, 29CM 프론트엔드 개발자 권형주입니다.

이번 포스팅에서는 기존 29CM 의 주요 도메인 중 하나인 상품 상세 페이지를Angular 에서 React 로 전환을 결정하게 된 이유, 전환 과정에서 어려웠던 점과 이를 해결해나간 과정들을 소개하고자 합니다.

React!!!!

🥁 React 전환을 결정하게 된 계기

저희 팀에서 Angular 에서 React 로 전환을 결정하게 된 가장 큰 계기는 Angular 개발자 채용의 어려움입니다.

비지니스는 점점 커져가는데 채용이 쉽지 않아 서비스 규모와 비교해 상대적으로 부족한 3명으로 구성된 프론트엔드팀으로 개발을 진행하고 있었고 더해서 목적 조직으로의 전환도 앞두고 있었죠.

또한 아래와 같은 문제들을 겪고 있기도 했었습니다.

  1. 한 번 배포하는 데에 평균 10~15분 정도 걸리는 이슈
  2. Docker 를 사용하고 있지만 Layer Caching 을 활용할 수 없고 Image Cache 를 사용하지 않는 환경이라 매번 빌드/배포를 반복해야 하는 상황
  3. 에러 로그를 남기지 않고 있어 배포 후 장애 디버깅의 어려움

마지막으로는 관리되고 있지 않는 어마어마한 레거시의 무덤들이 산재하고 있어 더 이상의 방목은 힘들다는 판단이 있었습니다.

레거시의 무덤 😥

이러한 이유들을 기반으로 팀 내에서 방향성에 대한 논의가 있었고 최종적으로는 React 전환을 결정하게 되었습니다.

🤔 React 전환 방향

React 전환에 앞서 하나의 고려사항이 있었습니다. 저희 백엔드 팀에서는 MSA 로 전환하는 과정에 있었는데요, 저희 프론트엔드팀도 Micro Frontend 를 장기적으로는 지향하고자 하는 마음이 있어 바로는 진행하지 못하더라도 우선 SPoF 부터 제거하는 것을 중점에 두고 있는 상황이었습니다.

SPoF 를 제거하기 위해 각각의 워크스페이스별 도메인을 분리하고 서버를 각각 띄우도록 구성했으며, 하나의 서버에 장애가 발생하더라도 다른워크스페이스 서버에는 접근이 가능하도록 진행하고자 했습니다..만

허허.. 이런..
진행 과정에서 몇 가지 문제가 발생했습니다.

앱 내에서 상품 상세 페이지 같은 경우 별도의 전용 웹뷰를 통해 사용하도록 개발이 되어 있었는데 이번 작업을 통해 페이지 주소가 바뀌게 됨으로써 추가적으로 대응이 필요한 상황이 생겼습니다.

대응을 하지 않으면 React 상품 상세 페이지를 띄웠을 때 위 처럼 웹뷰가 무한으로 push 되는 현상이 발생했기에 신규 도메인에 대한 대응은 필수불가결했습니다.

이에,

  1. 앱의 하위 버전에서는 기존 Angular 페이지로 연결을 시키고
  2. 앱의 신규 버전 부터는 React 페이지로 연결을 시키기로 했습니다.

모바일 팀과 논의 후 앱의 신규 버전부터 신규 도메인이 대응되어 있는지를 User-Agent 의 특정 값을 통해 판단하도록 협의했고, 이 값이 포함된 경우에는 “기존 Angular 페이지와 React 페이지 둘 다 정상 작동되도록 패치된 버전이다”는 것을 알려주는 용도로 사용했습니다.

그리고 React 페이지에 문제가 발생할 때는 이 값을 기준으로 피쳐플래그를 통해 기존 Angular 페이지로 롤백을 쉽게 할 수도 있었습니다.

nginx 설정에서는 클라이언트의 User-Agent 에 이 값이 포함되지 않거나 legacy 파라미터가 포함되어 넘어오는 경우에만 기존 Angular 페이지로 접속되도록 처리하고 그 외에는 신규 React 페이지로 연결되도록 설정해 주었는데요,

위 설정을 통해 기존 Angular 페이지로 접근하는 경우엔 User-Agent 와 접속 파라미터에 따라 둘 중 어느 페이지로 보여줄 지 선택이 가능하도록 만들어 좀 더 유연하게 대응할 수 있도록 했습니다.

🌝 배포 프로세스 개선

기존에는 젠킨스 스크립트에서 npm install & build 를 진행하고 있어서 이미지 캐시를 활용할 수 없는 구조였습니다.

신규 시스템에서는 도커 스트립트 내에서 npm install 과 build 를 하도록 진행했고, Sentry 에 소스맵 파일들을 업로드하는 것도 Docker 스크립트 내에서 처리하도록 수정하였습니다.

배포 시스템을 개선 후에 Layer Caching 과 Image Cache 를 활용할 수 있게 됨에 따라 캐시가 존재하는 경우 배포 시간을 10분에서 3분 내외로 줄일 수 있었습니다.

🏓 React 전환 과정에서 어려웠던 점

위에서 언급했던 것처럼 상품 상세 페이지에는 범접할 수 없는 레거시들이 존재했습니다 😭
React 전환 과정에서 어떤 상황에서 어떤 값이 사용되고, 또한 어떤 값이 어떤 용도로 쓰이는지 인지하기가 무척 어려웠죠.

부끄럽지만 기존 코드에서 한 파일의 라인 수가 2,000줄이 넘어가는 경우도 허다했습니다 😂

그럼에도 불구하고 여러 히스토리를 알고 계시던 동료분들의 도움으로 다행히 불필요한 코드도 많이 제거하면서 여러 위기들을 극복할 수 있었습니다.

역시 최고의 복지는 동료입니다

🎁 전환 후의 페이지 성능 측정

React 로 전환 후 Lighthouse 를 통해 페이지 성능을 측정해 보았는데요, Lighthouse 의 성능 점수는 측정하는 클라이언트 기기의 사양에 따라 점수가 다르게 나오긴 하지만 전후 비교를 위해 진행해보기로 했습니다.

Legacy Page (Angular)
New Page (React)

Lighthouse 측정 결과 기존 Angular 페이지 기준 성능 점수 72점에서 92점으로 오른 것을 확인할 수 있었는데요, 이는 실제 눈으로도 체감할 정도의 변화여서 매우 뿌듯했습니다 🌝

아직 최적화 할 구간이 많이 보이네요 😅

하지만 큰 페이지 전환을 하면 늘 그렇듯 마음 한 구석에 알 수 없는 불안감이 계속 있었는데요, 유저에게 배포가 나간 어느 날 불안감은 현실이 되고 말았습니다 😢

불안감. 빼꼼

바로 안드로이드 웹뷰에서 발생한 성능 이슈였는데 우선 현상 파악을 위해 Sentry 를 이용한 페이지 분석부터 진행하기로 했습니다.

분석 결과 HTML 렌더링하는 시간이 길어지면서 js 번들 파일들을 늦게 요청하는 이슈를 발견했습니다.

이를 해결하기 위해 최초에 받아오는 HTML 의 양을 줄여보기로 했으며, 슬라이더 컴포넌트들과 리뷰/Q&A 영역에 Lazy loading 도 적용해보기로 했습니다.

오? Lazy loading 적용으로 초기 렌더링 구간이 빨라진 것을 확인했지만 놀랍게도 또 다른 이슈를 발견했습니다!
js 번들 파일들을 요청 후에 가져오는 구간에서 오래 걸리는 것을요..

이에 번들링되는 파일의 용량을 줄이기 위해 웹뷰에서는 사용되지 않는 상단 메뉴바와 하단 푸터를 초기에 로드되지 않도록 수정했고, CLS 에 영향이 큰 컴포넌트 위주로 아래처럼 Dynamic Import 를 적용해 주었습니다.

Dynamic Import 적용 결과

변경 후 CPU 를 6x 로 감속 시킨 뒤 성능을 측정해 변화를 확인해봤습니다.

CPU 6x 감속 후에 진행한 성능 측정

스크립트 6940ms → 5903ms
렌더링 889ms → 757ms
페인팅 94ms → 91ms

아직 개선할 부분이 많이 보이지만 그래도 수치적으로도 확실히 개선된 결과를 보니 기분이 좋네요!

👋🏻 마치며

이번 글에서는 상품 상세 페이지의 React 전환에 대한 배경과 과정, 그 과정에서 겪었던 이슈들을 어떻게 해소했는지를 다루었으며, 전환한 페이지의 성능 최적화도 같이 소개드렸습니다.

React 전환 과정에 대한 세부적인 내용은 추후 기회가 될 때 별도의 글로 다뤄보려고 합니다.

이번 작업에 도움을 주신 동료 안가람, 전은미, 정상협, 김우성, 김평수, 강호길, 김가을, 정다해, 유가희님 감사합니다.

또한 디자인 QA 를 포함해 이번 프로젝트 마무리에 도움을 주신 송보은, 이조은, 정지은님에게도 감사를 전하고 싶습니다.

🙋🏻‍♂‍‍ 함께 성장할 동료를 찾습니다

29CM (무신사) 는 3년 연속 거래액 2배의 성장을 이루었습니다.

이제 더 큰 성장을 위해 기존 모놀리틱 서비스 구조를 마이크로서비스 구조로 전환하고, Angular 기반 프론트엔드 코드를 React 로 전환하는 등의 기술적인 시도를 진행하고 있습니다.

함께 성장하고 유저 가치를 만들어낼 동료 개발자분들을 찾습니다
많은 지원 부탁합니다!

🚀 29CM 채용 페이지 : https://www.29cmcareers.co.kr/

--

--