넥스트 프레임워크의 앱 라우터와 리액트 서버 컴포넌트가 최신 기술이라는 이유만으로 무조건 우리 서비스에 이득이 되는 것은 아닙니다. 토스뱅크 프레임워크 개발팀은 유지보수 모드에 들어간 기존 페이지 라우터를 대체하기 위해 앱 라우터 도입을 심도 있게 검토했습니다. 필요한 데이터를 각 구성 요소마다 나누어 가져오고 준비된 영역부터 먼저 보여준다는 점은 대단히 매력적이었습니다. 하지만 실제 서비스를 옮겨보고 매주 막히는 지점을 공유하며 검토한 결론은 결국 도입하지 않는 것이었습니다. 서비스의 안정성을 든든하게 지키며 체제 전환을 이루고 유지하는 데 드는 비용이 얻을 수 있는 이득보다 훨씬 컸기 때문입니다. 과연 어떤 치열한 고민과 기술적 질문들이 이 같은 결론을 이끌어냈는지 자세히 살펴보겠습니다. 이 글을 통해 최신 기술을 무작정 좇기보다 서비스 특성에 맞는 기술을 선택하는 기준을 세울 수 있을 것입니다.
=
넥스트 프레임워크 앱 라우터 도입, 우리 서비스에도 정말 유리할까요?
1. 소제목
준비된 영역부터 먼저 보여주면 사용자 경험이 더 좋아질까요? 기존에는 서버에서 화면을 그릴 때 필요한 모든 데이터를 한 함수에서 모아서 한 번에 가져오곤 했습니다. 전체 페이지 단위로만 쓸 수 있는 구조이다 보니 하나의 프로그램 인터페이스 요청만 실패해도 정상적으로 받은 데이터까지 전부 다시 요청하는 비효율이 있었습니다. 새로운 방식인 앱 라우터에서는 데이터를 가져오는 구성 요소를 잘게 나누고 각각을 지연 표시 기능으로 감싸서 준비된 영역부터 화면에 띄울 수 있습니다. 마치 여러 개의 상자가 차례대로 도착하는 것처럼 사용자에게 더 빠른 반응 속도를 체감하게 해 줄 수 있는 구조입니다. 토스뱅크의 화면은 대부분 모바일 응용 프로그램 안의 웹뷰 환경으로 이루어져 있으며 요소가 주로 세로 방향으로 길게 쌓입니다. 이처럼 세로로 쌓이는 구조에서도 영역을 따로따로 보여주는 것이 자연스러운지 직접 실험을 통해 확인해 보았습니다.
세 영역에 각각 서로 다른 지연 시간을 두고 브라우저가 화면을 언제 그리는지 정밀하게 녹화하여 분석했습니다. 모바일 웹뷰는 주로 안드로이드 진영의 크로미움 엔진과 아이폰 진영의 웹킷 엔진을 바탕으로 구동되기에 두 엔진을 모두 살펴보았습니다. 첫 콘텐츠가 그려지는 시점이 크로미움에서는 아주 짧은 시간이 걸렸지만 웹킷에서는 마지막 영역이 준비될 때까지 표시를 크게 지연시켰습니다. 화면을 그리기 전에 콘텐츠가 충분한지 자체적인 기준으로 판단하는 특성 때문에 표시가 늦어지는 현상이 발생했습니다. 이 문제를 우회하기 위해 화면 위에 눈에 보이지 않는 요소를 추가하자 웹킷의 첫 표시 시점이 눈에 띄게 빨라졌습니다. 두 엔진 모두 준비된 영역부터 그리기 시작하는 방향으로 유도하는 데 성공했습니다.
준비된 영역부터 보여주는 방식은 브라우저 엔진에 따라 다르게 동작하며, 서비스 특성에 맞는 꼼꼼한 검증이 필수적입니다.
2. 소제목
화면이 먼저 그려질 때 발생하는 레이아웃 흔들림 문제 화면이 빠르게 그려지기 시작하자 다음 단계에서 예상하지 못한 새로운 문제가 곧바로 눈에 보이기 시작했습니다. 스켈레톤 화면이 실제 콘텐츠로 바뀔 때 각 영역의 높이가 달라지는 현상이 발생했습니다. 세로로 길게 쌓인 화면 구조에서는 위쪽 영역의 늘어난 높이 때문에 사용자가 이미 보고 있던 아래쪽 내용까지 그만큼 아래로 밀려 내려갔습니다. 이러한 시각적 흔들림을 줄이기 위해 스켈레톤의 높이를 실제 콘텐츠가 들어갈 높이와 최대한 비슷하게 맞추는 작업을 진행했습니다. 그 결과 레이아웃 이동값이 크게 낮아지며 화면이 훨씬 안정적으로 변하는 것을 확인할 수 있었습니다.
하지만 이러한 조치는 개발 과정에서 상당한 추가 노력을 요구한다는 명확한 한계를 지니고 있었습니다. 새로운 화면 영역을 추가할 때마다 별도의 로딩 화면을 정교하게 만들어야 했고 콘텐츠가 바뀔 때마다 높이를 다시 맞추어야 했습니다. 영역을 잘게 나누어 먼저 보여주는 데서 얻는 미미한 이득보다 화면이 흔들리지 않도록 지속해서 관리하는 부담이 훨씬 컸습니다. 모바일 응용 프로그램 내 웹뷰 환경에서는 사용자가 스크롤을 내리는 속도가 매우 빠르기 때문에 미세한 흔들림도 전체적인 품질 저하로 이어질 수 있습니다. 결국 사용자에게 더 나은 경험을 준다는 명목 하에 도입한 기술이 오히려 개발 생산성을 떨어뜨리고 유지보수를 복잡하게 만드는 원인이 되었습니다.
영역별 스트리밍 표시는 시각적 흔들림을 유발하며, 이를 관리하는 비용이 실제 사용자 경험 개선 효과보다 클 수 있습니다.
3. 소제목
서버 컴포넌트를 우리 코드베이스에 얼마나 활용할 수 있을까요? 스트리밍 표시 기능을 넓게 활용하기 어렵겠다는 판단을 내렸지만 그것만으로 앱 라우터 도입 검토를 완전히 접을 수는 없었습니다. 스트리밍을 쓰지 않더라도 리액트 서버 컴포넌트 자체에 걸고 있던 다른 기대치가 여전히 남아 있었기 때문입니다. 그중에서 가장 매력적이었던 부분은 클라이언트 번들 크기를 혁신적으로 줄일 수 있다는 점이었습니다. 서버 컴포넌트의 구현 내용과 거기서만 사용하는 무거운 의존성 패키지들은 클라이언트 측 번들 파일에서 아예 빠지기 때문에 초기 로딩 속도에 큰 도움이 됩니다.
부차적으로는 데이터를 가져오는 코드를 훨씬 깔끔하고 직관적으로 정리할 수 있다는 장점도 존재했습니다. 기존 방식에서는 인증 정보를 특정 함수에서 꺼내 서버용 프로그램 인터페이스 함수에 일일이 넘겨주어야 했습니다. 하지만 앱 라우터의 서버 코드 환경에서는 헤더 정보를 직접 읽어올 수 있어 인증을 챙기는 작업이 데이터를 가져오는 함수 내부로 자연스럽게 들어갑니다. 마치 브라우저에서 쿠키가 알아서 실려 나가는 것처럼 서버 환경에서도 호출하는 쪽에서 인증을 따로 신경 쓰지 않아도 됩니다. 이처럼 아키텍처 관점에서 코드를 간결하게 만들 수 있는 잠재력은 개발자들에게 큰 매력 포인트로 다가왔습니다.
서버 컴포넌트는 클라이언트 번들 크기를 줄이고 데이터 호출 코드를 정리하는 강력한 구조적 이점을 제공합니다.
4. 소제목
서버 환경 설정과 클라이언트 환경의 분기 처리 방식 서버 전용 헤더 정보를 클라이언트 컴포넌트에서 직접 사용하는 것은 구조적으로 불가능하다는 기술적 장벽이 있었습니다. 심지어 서버에서 렌더링이 진행되는 동안에도 클라이언트와 섞이는 구간에서는 동일한 문제가 발생했습니다. 관련 모듈을 가져오는 순간 그 파일 자체가 브라우저 영역으로 절대 나갈 수 없게 되기 때문에 한 파일 안에서 조건문으로 나누어 쓰는 방식은 통하지 않았습니다. 이 문제를 해결하기 위해 도입한 방법이 바로 패키지의 환경별 분기 처리 구조였습니다.
설정 파일의 조건부 내보내기 기능을 활용하여 서버 컴포넌트용 구현과 일반 클라이언트용 구현을 완전히 분리했습니다. 이를 통해 코드를 호출하는 쪽에서는 복잡한 분기 없이 동일한 경로로 가져다 쓸 수 있도록 편의성을 높였습니다. 서버 전용 구현에서만 헤더 정보를 읽어 인증 정보를 붙이고 브라우저용 구현은 기존 방식 그대로 유지했습니다. 이처럼 복잡한 환경 분기를 수동으로 관리해야 하는 구조는 새로운 기술 도입 시 반드시 감수해야 할 숨겨진 비용입니다. 단순한 기능 적용을 넘어 전반적인 패키지 관리 체계를 손봐야 하므로 팀 전체의 기술 부채로 작용할 우려가 큽니다.
서버와 클라이언트 환경의 엄격한 분기 처리는 추가적인 설정 비용과 관리 부담을 발생시킵니다.
5. 소제목
기존 페이지 라우터 유지보수와 새로운 체제로의 전환 비용 현재 사용 중인 페이지 라우터가 유지보수 모드에 들어갔다고 해서 당장 서비스에 치명적인 문제가 발생하는 것은 아닙니다. 보안 패치와 기본적인 버그 수정은 계속해서 이어지기 때문에 안정성을 최우선으로 하는 금융 서비스 환경에서는 여전히 충분한 생명력을 가지고 있습니다. 반면 새로운 앱 라우터로 완전히 전환하는 과정은 기존에 작성된 수많은 코드를 대수술하는 작업과 맞닿아 있습니다. 모든 화면과 라우팅 구조를 새로 작성하고 예상치 못한 호환성 문제를 해결하는 데 소요되는 시간은 프로젝트 일정에 큰 부담이 됩니다.
개발자 회의를 거치며 내린 최종 결론은 지금 당장 무리하게 새로운 체제로 전환하지 않는 것이 가장 현명하다는 판단이었습니다. 우리 서비스가 얻을 수 있는 실질적인 이득에 비해 기존 안정성을 지키며 전환하고 유지하는 비용이 너무나 압도적으로 컸습니다. 기술의 최신 유행을 좇는 것보다 현재의 안정적인 서비스를 탄탄하게 지키는 것이 비즈니스 관점에서 훨씬 더 가치 있는 선택이었습니다. 모든 팀이 최신 프레임워크를 도입한다고 해서 우리 회사 역시 무조건 따라갈 필요는 없다는 중요한 교훈을 얻었습니다.
최신 기술의 유행보다 서비스의 안정성과 전환에 드는 실질적인 비용을 냉정하게 비교하는 것이 중요합니다.
6. 소제목
서비스 특성에 맞춘 프레임워크 선택의 중요성과 앞으로의 방향성 기술 생태계는 언제나 빠르게 변화하고 새로운 도구와 프레임워크가 끊임없이 쏟아져 나오기 마련입니다. 그렇기 때문에 개발자들은 새로운 기술의 화려한 장점뿐만 아니라 우리 서비스의 아키텍처와 얼마나 잘 어울리는지 꼼꼼히 따져봐야 합니다. 이번 토스뱅크의 사례처럼 아무리 훌륭한 장점을 가진 기술이라도 특정 환경에서는 오히려 독이 되거나 과도한 유지보수 비용을 유발할 수 있습니다. 앞으로도 기술 그룹을 중심으로 다양한 대안을 실험하고 실무에 적합한지 검증하는 문화를 지속해 나갈 계획입니다.
기술 도입은 단순한 개발자의 호기심 충족이 아니라 고객에게 안정적인 서비스를 제공하기 위한 수단이어야 합니다. 새로운 기술을 검토하는 과정에서 마주치는 수많은 질문과 실패 경험은 팀의 소중한 자산으로 쌓이게 됩니다. 독자 여러분께서도 새로운 기술 도입을 고민하고 계신다면 남들의 시선보다는 우리 회사의 서비스 특성과 팀의 역량을 먼저 돌아보시기 바랍니다. 철저한 사전 검증과 비용 대비 효과 분석을 거친다면 언제나 우리 서비스에 가장 알맞은 최선의 결정을 내릴 수 있을 것입니다.
기술 도입은 유행을 따르는 것이 아니라 서비스의 특성과 안정성을 최우선으로 고려하는 결정이어야 합니다.
자주 묻는 질문
=
🔗 함께 읽으면 좋은 글: 몽골 오랑터거 화산, 한국인 여행 인플루언서 추락 사망 사건의 충격