Skip to main content

Vue+express에서 Next.js로, '숨고'의 마이그레이션 (1,2)

About 2 minJavaScriptTypeScriptVue.jsNext.jsArticle(s)blogyozm.wishket.comjsjavascripttstypescriptvuevuejsvue-jsvercelnextjs

Vue+express에서 Next.js로, '숨고'의 마이그레이션 (1,2) 관련

Vue.js > Article(s)

Article(s)

Vue+express에서 Next.js로, '숨고'의 마이그레이션 (1) | 요즘IT
Vue+express에서 Next.js로, '숨고'의 마이그레이션 (1)

[FEConf2023에서 발표한 Vue+express였던 서비스가 이세계에선 Next.js? (프레임워크 마이그레이션)open in new window][1]를 정리한 글입니다. 발표 내용을 2회로 나누어 발행합니다. 1회에서는 숨고의 서비스 프레임워크를 Vue에서 Next로 전환하게 된 배경과 사전 작업에 대해 살펴봅니다. 2회에서는 페이지 url 단위 마이그레이션을 진행하며 겪었던 문제점과 개선 과정에 대해 이야기합니다. 본문에 삽입된 이미지의 출처는 모두 이 콘텐츠와 같은 제목의 발표 자료로, 따로 출처를 표기하지 않았습니다. 발표 자료는 FEConf2023 홈페이지open in new window에서 다운로드할 수 있습니다.


숨고 개발팀의 프레임워크 마이그레이션

숨고에서 기술 부채 해결, 팀의 생산성을 개선하는 업무를 맡고 있는 프론트엔드 엔지니어 정지만입니다. 이 글에서는 서비스의 프레임워크를 Vue에서 Next로 전환한 경험을 공유하고자 합니다.

프레임워크 마이그레이션 배경, 점진적인 페이지 단위 마이그레이션, 마이그레이션 과정에서 고려해야 하는 포인트, 그리고 마이그레이션 중에 겪었던 이슈와 그걸 해결한 과정을 공유합니다.

1. Next.js 마이그레이션 결정 배경

프레임워크 마이그레이션은 기존에 사용하던 기술 스택이 더 이상 유지보수가 불가할 때, 새로운 프레임워크의 성능이 필요할 때, 또는 시장을 점유하는 기술을 따라갈 필요가 있을 때 고려됩니다.

1
1

숨고 팀의 경우, Vue2 기반의 서버 사이드 렌더링(SSR) 가이드open in new window를 참고하여 SSR을 구축했었는데, 이는 SEO(검색엔진 최적화)와 같은 여러 이점을 제공했습니다. 그러나 시간이 지나면서 Vue2의 LTS(장기 지원) 종료가 예정되어 있었고, 자체 구축된 프레임워크는 커뮤니티 지원이 부족하여 유지보수에 어려움이 예측되었습니다.

2
2

이러한 상황 속에서, 서비스 규모의 확장과 함께 기술 스택의 한계점이 명확해졌습니다. 메모리 누수 문제와 느린 빌드 시간, 그리고 불만족스러운 LCP(Largest Contentful Paint) 성능이 발견되었습니다. 이러한 문제들을 해결하기 위해 거대한 기술 스택을 기존 프레임워크 내에서 개선하는 것보다, 다른 프레임워크로의 전환을 통해 새로운 시작을 하는 것이 더 현명한 결정으로 판단되었습니다.

3
3

2. 프레임워크 선정 이유: 효율적인 프로덕트/조직 운영

Vue3기반의 Nuxt.js 대신 Next.js를 선택한 이유는 다음과 같습니다. Next.js는 스테이블한 프레임워크로, 숨고 팀의 복잡한 제품 의존성을 관리하기에 적합했습니다. 또한, 리액트는 메이저 업데이트가 상대적으로 용이하여, 제품을 최신 상태로 유지관리 하는 데 유리한 점을 제공했습니다. 리액트의 시장 점유율은 채용 시장에서도 긍정적인 영향을 미쳤으며, 리액트 기반의 엔지니어가 많은 것도 Next.js를 선택하는 데 한몫했습니다. 결국에는 빠른 성장을 해야 하는 스타트업의 특성을 고려하여, 운영적인 측면에서 이점을 취할 수 있는 Next.Js를 선택하게 되었습니다.

4
4

3. 상용 B2C 서비스의 프레임워크 마이그레이션을 위한 과제

마이그레이션 과정에서 가장 먼저 고려한 점은 점진적인 마이그레이션입니다. 제품의 규모가 상당히 크기 때문에 모든 모듈을 한 번에 마이그레이션 하는 것은 실질적으로 불가능했습니다. 이러한 점진적 마이그레이션은 기능 개발과 유지보수를 지속하면서도 제품의 안정성을 유지할 수 있게 해줍니다. 점진적 마이그레이션을 실현하기 위한 두 가지 방법은 페이지 URL 단위 마이그레이션과 컴포넌트 단위 마이그레이션입니다. 숨고 팀은 페이지 단위 마이그레이션을 선택했습니다. 이 방식은 서비스의 각 페이지를 차례로 새 프레임워크로 이전함으로써, 기존 서비스와 새 서비스가 동시에 운영되며 점진적으로 전환될 수 있도록 합니다.

5
5

품질 관리는 마이그레이션 프로젝트에서 중요한 두 번째 과제입니다. 특히 B2C 서비스인 경우, 검색 엔진 최적화(SEO)가 핵심 요소입니다. 숨고 서비스의 가시성과 접근성을 높이기 위해 SEO를 중요하게 고려해야 합니다. 사용자의 전환율 역시 매우 중요한 지표입니다. 서비스의 성공은 사용자가 원하는 작업을 효과적으로 수행할 수 있게 하는 데 있으므로, 전환율은 사용자 경험의 질을 반영합니다.

마지막으로 인프라는 Next.js와 같이 서버 레벨에서 동작하는 프레임워크를 도입할 때 특별히 고려해야 할 요소입니다. 서버의 구성이나 설정을 변경해야 할 수도 있으므로, 인프라 수준에서의 준비와 테스트가 필수적입니다.

4. 점진적인 마이그레이션을 위한 사전 작업: 인프라 관리

점진적인 마이그레이션 전에는 다양한 사전 작업이 필요합니다. 예를 들어, 기존 Vue로 작성된 코드와 라이브러리를 React로 재설치하고, 모듈을 React의 hooks로 재설계해야 합니다. 로그인 상태의 유지, 인프라의 구축과 같은 기술적 과제도 중요합니다.

6
6

특히 인프라의 경우, AWS의 로드 밸런싱 기능을 활용해 Next.js와 Vue.js로부터 서빙되는 URL을 관리하는 방법을 선택했습니다. 이러한 인프라의 변화는 다양한 로드밸런서 중에서도 특히 레이어 7 애플리케이션 로드밸런서의 필요성을 강조합니다.

7
7

Next.js 배포 직후 잠시 동안 나타나는 404에러를 방지하기 위해 동기화 작업이 필요합니다. 배포 프로세스에서는 Next.js 서버가 정상 구동된 후에 Vue와 ALB(애플리케이션 로드 밸런서)를 배포하는 순서를 정하는 것이 중요합니다.

8
8

생산성 향상을 위해서는 리버스 프록시 설정을 자동화하여 배포 파이프라인에 통합하는 접근 방식이 효과적입니다. CI/CD 파이프라인에 Ingress 설정을 자동화하면 테스트 환경이 추가되더라도 자동으로 의도한 테스트 환경으로 조정됩니다.

9
9

카나리 배포는 사이드 이펙트 조기감지 및 AB test가 가능하다는 이점이 있지만, Vue와 Next 모두를 유지보수 해야 한다는 점과 Sticky Session 문제 때문에 보류되었습니다.

10
10

마이그레이션 과정에서 도메인 분리에 대한 고민도 있었습니다. 하지만 SEO 관리의 중요성 때문에 도메인 분리 방식을 채택하지 않았습니다. 검색 엔진은 도메인 변경을 새로운 웹 페이지로 판단할 수 있습니다. 이는 마이그레이션 후 검색 결과 순위에 영향을 줄 수 있으므로, SEO에 추가적인 모니터링이 필요할 수 있습니다.

11
11

지금까지 내용을 정리하면, 프레임워크 마이그레이션을 위해 점진적인 마이그레이션을 선택했습니다. 그리고 점진적으로 마이그레이션 하기 위해 페이지 URL 단위로 서비스를 마이그레이션 했습니다. 마이그레이션 하기 전에 사전 작업이 많이 필요했지만, 그중에서도 인프라에 관한 내용을 좀 더 중점적으로 말씀을 드렸습니다.

Vue+express에서 Next.js로, '숨고'의 마이그레이션 (2) | 요즘IT
Vue+express에서 Next.js로, '숨고'의 마이그레이션 (2)

5. 점진적인 마이그레이션: 페이지 url 단위 마이그레이션

새로운 프레임워크로의 마이그레이션 과정에서는 사용자 경험과 SEO 최적화를 고려한 페이지 전환 전략의 중요성이 강조됩니다. 특히, SPA(Single Page Application)와 SSR(Server-Side Rendering)의 결합은 현대 웹 애플리케이션 개발에서 널리 채택되고 있는 패턴입니다. 이러한 접근 방식은 첫 페이지 진입 시 SSR을 통해 사용자에게 초기 페이지를 제공하고, 이후의 내비게이션은 히스토리 API를 기반으로 하는 SPA 방식으로 매끄럽게 전환되어 사용자 경험을 향상시킵니다. 또한, 이 방법은 검색엔진이 서버에서 렌더링된 HTML을 쉽게 인덱싱할 수 있도록 하여 SEO에 유리합니다.

12
12

그러나 두 가지 이상의 프레임워크가 공존하는 마이그레이션 상황에서는 SPA처럼 매끄러운 페이지 전환을 구현하는 것에 몇 가지 도전 과제가 있습니다. 기존에는 사용자가 첫 페이지에 진입할 때 필요한 모든 자바스크립트 번들을 로드함으로써 이후 페이지 전환 시에도 빠르고 매끄러운 경험을 제공할 수 있었습니다. 그러나 두 프레임워크가 공존하는 경우, 예를 들어 리스트 페이지에서 다음 페이지로의 전환 시 필요한 React 앱을 렌더링할 자바스크립트 번들이 미리 로드되어 있지 않다면, 페이지 전환 과정에서 404 에러 페이지가 노출될 수 있습니다.

13
13

이 문제를 해결하는 한 가지 방법은 하이퍼링크 방식을 통한 페이지 전환입니다. 사용자가 페이지를 전환할 때마다 새로운 페이지 요청이 발생하고, 이에 따라 새로운 HTML과 필요한 자바스크립트 번들이 로드됩니다. 이 방식은 HTML의 기본적인 앵커 태그를 사용하거나 프레임워크에서 제공하는 라우팅 이벤트를 직접 제어하여 구현할 수 있습니다. 마이그레이션된 경로에 따라 지속적인 변경을 피하기 위해 더 효율적인 라우팅 이벤트 제어 방식을 선택하는 것이 좋습니다.

14
14

결론적으로, 두 종류의 프레임워크가 공존하는 환경에서는 SPA와 같은 매끄러운 페이지 전환을 기대하기 어렵습니다. 이를 극복하기 위해서는 사용자가 새로운 페이지로 전환할 때마다 전통적인 하이퍼링크 방식을 적용하거나 라우팅 이벤트를 직접 제어해야 합니다. 이러한 접근 방식을 통해 새로운 프레임워크로의 마이그레이션 과정에서도 사용자 경험을 최적화하고, 프로젝트의 전환 과정을 원활하게 관리할 수 있습니다.

15
15

6. 페이지 단위 마이그레이션의 단점: 전환 지연

페이지 단위 마이그레이션 전략을 선택하면서, 숨고 팀은 초기에 오버헤드가 상대적으로 적다는 장점을 누릴 수 있었습니다. 이 접근 방식은 사전 작업의 복잡성에도 불구하고, 코드 레벨에서의 특별한 주의가 필요 없이, 프로젝트의 관심사를 잘 분리하고 단위별로 개발을 용이하게 했습니다. 그러나 이러한 전략의 가장 큰 단점은 페이지 전환 시 발생하는 배포 지연이었습니다.

16
16

기존의 방식에서는 페이지 전환 속도가 매우 빠르며, 사용자가 히스토리 API를 기반으로 한 소프트 내비게이션을 통해 빠르게 페이지를 전환할 수 있었습니다. 이는 퍼널을 통한 사용자의 원활한 이동을 가능하게 하며, 최종적으로 전환율의 증가로 이어졌습니다.

17
17

하지만, 마이그레이션된 페이지에서 하이퍼링크 방식으로 페이지 전환을 구현하면서 발생한 지연은 사용자 경험을 저하시켰고, 이는 비즈니스적으로 큰 문제가 되었습니다.

18
18

첫 페이지로 리스트 페이지를 마이그레이션하면서, 우리는 이 지연이 비즈니스 지표, 특히 전환율에 영향을 미칠 것이라는 예상 문제에 직면했습니다. 개발팀은 마이그레이션의 순서와 방식에 있어서는 자신감이 있었지만, QA 단계에서 비즈니스 조직과 함께 모니터링하는 과정에서 문제가 명확해졌습니다. 이에 따라, 제품 소유자(PO) 측에서는 전환율 하락을 우려하여 배포의 1% 롤백을 제안했고, 결국 개발팀도 이에 동의하여 배포를 미루기로 결정했습니다.

배포 지연은 마이그레이션 과정에서 큰 낭비로 여겨졌습니다. 기존 페이지에 새로운 기능이 추가되면, 마이그레이션이 거의 완료된 페이지에도 해당 기능을 동기화해야 하는 번거로움이 발생했습니다. 이러한 과정은 개발 효율성을 저하시키고, 무엇보다도 비즈니스적으로 중요한 전환율에 직접적인 영향을 미쳤습니다. 특히 B2C 서비스에서는 사용자가 마지막 페이지까지 원활하게 전환되어야만 최종적인 성과가 나타나는 구조인데, 디테일 페이지로의 전환 지연은 이러한 성과 달성에 큰 장애가 되었습니다.

19
19

이러한 문제에 직면하여, 프론트엔드와 PO 챕터의 합의 하에 리스트 페이지의 배포는 무기한 연기되었습니다.

7. 기술적 대안 검토: 컴포넌트 단위 마이그레이션

이러한 맥락에서, 우리 개발팀은 컴포넌트 단위 마이그레이션을 위한 유력한 대안으로 아이 프레임(iFrame)을 고려하게 되었습니다. 아이 프레임을 사용하는 접근 방식은 특히 리스트 페이지와 같은 복잡한 페이지의 마이그레이션 시 다양한 이점을 제공합니다.

아이 프레임을 활용한 마이그레이션은 기존 뷰(Vue) 애플리케이션의 헤더나 사이드바는 그대로 유지하면서 내부 콘텐츠만 Next.js로 마이그레이션하는 방식입니다. 이 접근법의 가장 큰 장점은 페이지 전환 시 소프트 내비게이션이 가능하다는 것입니다. 이는 사용자 경험을 크게 향상시키며, 페이지 로딩 시간을 단축시키는 효과를 가집니다. 또한, 배포 단위를 작게 가져갈 수 있어, 새로운 기능을 빠르게 개발하고 배포하는 데 유리합니다.

하지만 이러한 접근법은 몇 가지 고려해야 할 점이 있습니다. 첫째로, 페이지와 아이 프레임 사이의 통신 프로토콜 설계가 필요합니다. 이는 주로 포스트 메시지 기반의 이벤트로 정의되며, 페이지의 유지보수 기간 동안 지속적으로 관리되어야 합니다. 또한, 마이그레이션이 완료된 후에는 아이 프레임을 제거하는 작업도 필요합니다.

둘째로, SEO(검색엔진 최적화)에 미치는 영향을 신중하게 고려해야 합니다. 아이 프레임을 사용하면 마크업 레벨에서 상당한 변화가 발생하며, 이는 SEO에 부정적인 영향을 줄 수 있습니다. 공식적인 문서나 레퍼런스에서 아이 프레임의 SEO 영향에 대해 명확한 언급을 찾기 어려웠고, 여러 칼럼에서 아이 프레임이 SEO에 좋지 않다는 의견을 찾아볼 수 있었습니다.

이러한 이유로, 아이 프레임의 도입은 계속해서 검토 중인 상태입니다. 그러나 아이 프레임의 장점이 분명히 많기 때문에, 세션이 필요한 페이지에서는 이를 적극적으로 고려해볼 가치가 있습니다.

21
21

8. 정책적 해결: 프로덕트 팀과의 협업을 통한 비즈니스적 접근

대안 검토에서 의미 있는 대안이 도출되지 못했을 때, 기존의 매커니즘을 유지하며 정책적인 조정을 통해 문제를 해결하는 것이 가장 효율적인 전략일 수 있습니다. 숨고 팀은 페이지 단위 마이그레이션 과정에서 겪었던 전환 지연 문제를 기술적 변화가 아닌, 정책적 접근으로 해결하기로 결정했습니다.

이 과정에서 프로덕트 팀과의 긴밀한 협업이 이루어졌습니다. 첫 번째 단계로 사용자 지표를 기반으로 퍼널을 재정의했습니다. 특정 페이지 전환 인터랙션이 사용자 경험에 미치는 영향을 민감하게 측정하여, 그에 따라 마이그레이션의 우선순위를 재조정했습니다. 이렇게 재구성된 퍼널 내에서 리치 임팩트를 고려해 순차적으로 페이지를 마이그레이션을 진행하였습니다.

22
22

두 번째로는 브라우저 새로고침을 최소화하는 것을 목표로 삼았습니다. 초기에는 Vue에서 Next.js로 전환 시 로딩 시간이 길어 사용자 경험이 저하되는 문제가 있었습니다. 그러나 Next.js의 로딩 시간을 최적화하여, 사용자가 마이그레이션된 페이지를 경험할 때 로딩 지연을 최소화할 수 있도록 조치했습니다.

23
23

마지막으로, 마이그레이션 페이지의 LCP(Largest Contentful Paint)를 2.5초 이내로 제한하는 기준을 설정하여, QA 과정에서 이 기준을 충족하지 못하는 페이지는 배포를 지연시키는 결정을 내렸습니다.

24
24

이러한 정책적 조정을 통해, 퍼널 마지막 전환 과정에서의 지연은 거의 체감되지 않는 수준에 이르렀습니다. 또한 마이그레이션된 페이지의 퍼널이 전환율 지표를 유지하며 성공적으로 마이그레이션될 수 있었습니다.

마이그레이션을 마치고 나서, 숨고 팀은 아무리 프레임워크를 마이그레이션하는 기술 부채를 해결하는 과정이라도 그 의사결정을 비즈니스 조직과 함께한다면 좀 더 생산적인 결과를 낼 수 있다는 교훈을 얻을 수 있었습니다.

25
25

9. 앞으로의 과제

마이그레이션 프로젝트는 처음에는 단순히 전환율 지표를 유지하며 마이그레이션을 성공적으로 완료하는 데 중점을 뒀습니다. 그러나 지금은 그 목표를 확장하여, 마이그레이션을 통해 비즈니스적인 성과까지 이끌어내는 것으로 재설정했습니다. 프로젝트로부터 구체적인 성과가 나타난다면, 이는 마이그레이션의 필요성을 뒷받침하고, 비즈니스 조직과의 원활한 협의를 가능하게 할 것입니다.

26
26

더불어, 마이그레이션의 효율성을 높이기 위해 아이프레임을 사용하는 대안에 대해서도 계속해서 탐구해 볼 생각입니다. 리소스의 효율적 사용과 작업 간 충돌을 최소화하여 마이그레이션 과정을 개선하는 데 중요한 역할을 할지도 모릅니다.


이찬희 (MarkiiimarK)
Never Stop Learning.

  1. FEConf2023에서 발표된 'Vue+express였던 서비스가 이세계에선 Next.js? (프레임워크 마이그레이션)'/정지만 숨고 프론트엔드 엔지니어 ↩︎