News Feed

서버 사이드인가, 클라이언트 사이드인가…현대 웹 아키텍처의 해법

컨텐츠 정보

  • 조회 465

본문

지난 수십 년 동안 웹 아키텍처는 익숙한, 솔직히 말해 이제 신물이 나는 패턴을 따라왔다. 지배적인 접근방식이 등장해 광범위하게 채택되고, 이후 실제 환경에서 균열이 드러나면서 결국 지난 접근방식이 망가뜨린 모든 것을 고치겠다고 약속하는 새로운 “모범 사례”로 대체되는 패턴이다. 

2000년대 초반을 주도한 서버 렌더링 방식의 모놀리식 애플리케이션에서도 이 패턴을 봤고, 2000년대 후반과 2010년대 초반 리치 클라이언트 사이드 애플리케이션을 향한 대대적인 전환에서도 봤다. 가장 명확한 사례는 브라우저에서 데스크톱과 비슷한 상호작용성을 약속했던 싱글 페이지 애플리케이션의 부상이었다. 그러나 자바스크립트 번들이 몇 메가바이트에 달하고 로딩 화면에는 아무것도 표시되지 않고 그저 페이지가 검색되도록 하기 위해 SEO 우회책에 몇 년 동안이나 의지하는 등, 실제로 이어진 결과는 많은 부분에서 약속과는 전혀 달랐다. 

그리고 이제 서버 사이드 렌더링이 다시 유행하고 있다. 사람들은 클라이언트 사이드 아키텍처가 한계에 이르러 다시 서버로 돌아가는 것일까? 엄밀히 말해 그건 아니다.

서버 사이드 렌더링과 클라이언트 사이드 접근방식, 두 가지 모두 예전과 다름없이 매력적이다. 지금이 예전과 다른 점은 툴이나 기술의 지속 가능성이 아니라 사람들이 구축하는 시스템과 그 시스템에 두는 기대치에 있다.

결론은? 웹 애플리케이션을 구축하기 위한 하나의 “올바른” 모델은 더 이상 존재하지 않는다는 것이다. 그 이유를 살펴보자.

웹사이트에서 분산 시스템으로

현대 웹 애플리케이션은 더 이상 단순한 “사이트”가 아니라 여러 런타임, 글로벌 콘텐츠 전송 네트워크, 엣지 캐시, 백그라운드 워커, 그리고 점점 더 복잡해지는 데이터 파이프라인에 걸쳐 있는, 장기간 지속되는 고도의 상호작용 시스템이다. 사람들의 기대에 부응하기 위해서는 즉각 로드돼야 하고 열악한 네트워크 조건에서도 높은 반응성을 유지해야 하며, 뭔가 잘못된 상황에서도 문제를 거칠지 않게 표출해야 한다.

이 환경에서 아키텍처에 대한 맹목적 추종은 이내 짐이 된다. “모든 요소는 서버에서 렌더링돼야 한다”거나 “모든 상태는 브라우저에 속한다”와 같은 절대주의는 확고하게 들리지만 막상 프로덕션 시스템에서는 거의 살아남지 못한다.

현실은 복잡하다. 이 복잡함은 실패가 아니라 웹이 그동안 얼마나 성숙해졌는지를 보여주는 하나의 지표다.

아키텍처 절대주의의 문제

강한 의견은 특히 규모가 커질수록 매력적이다. 의사결정 피로를 줄이고, 온보딩을 더 쉽게 만들어 준다. “우리는 SPA만 구축한다” 또는 “우리는 SSR 우선 기업”이라는 선언은 모호함을 제거하기 때문에 마치 전략처럼 느껴진다.

문제는 실제 애플리케이션은 그 의견에 따라 움직이지 않는다는 점이다.

하나의 현대적 SaaS 플랫폼에는 서로 매우 다른 여러 워크로드가 포함되는 경우가 많다. 공개 랜딩 페이지와 문서에는 빠른 첫 콘텐츠 표시, 예측 가능한 SEO 동작, 그리고 공격적인 캐싱이 필요하다. 반면 인증된 대시보드에는 실시간 데이터, 복잡한 클라이언트 사이드 상호작용, 그리고 UI가 변경될 때마다 서버 왕복을 감내할 수는 없는 장기간 유지되는 상태가 필요할 것이다.

이런 모든 부분에 하나의 렌더링 전략을 강제하려고 시도하면 아키텍처 마찰이 발생할 수밖에 없고, 실제로 많은 팀이 이를 경험하고 있다. 여기저기서 예외가 발생하고 “이번 한 번만” 로직이 나타난다. 시간이 지나면 아키텍처는 처음부터 이와 같은 절충을 명시적으로 인정하는 아키텍처보다 더 이해하기가 어려워진다.

과거로의 회귀가 아닌 확장

서버 사이드 렌더링에 대한 지금의 관심을 기본으로의 회귀라는 간단한 설명으로 넘기고 싶은 생각이 들 수 있지만 실제 환경에서 이 설명은 금방 타당성을 잃는다.

전통적인 서버 렌더링 애플리케이션의 기반은 짧은 요청 수명 주기다. 서버는 HTML을 생성해서 브라우저로 보내고, 다음 요청이 올 때까지 사용자에 대해서는 거의 망각했다. 상호작용이란 전체 페이지 리로드를 의미했으며 상태는 거의 전적으로 서버에 존재했다.

현대의 서버 렌더링 애플리케이션이 동작하는 방식은 이것과는 큰 차이가 있다. 많은 경우 첫 HTML은 출발점에 불과하다. 이 HTML은 “하이드레이션”되고 강화되며, 첫 렌더링 이후 클라이언트 사이드 로직이 이를 이어받아 계속 유지한다. 서버는 더 이상 전체 상호작용 루프를 소유하지 않지만 그렇다고 사라진 것도 아니다.

서버 렌더링을 버리지 않고 고수한 생태계(대표적으로 PHP)들도 계속 번성했다. 예측 가능한 실행 모델, 단순명료한 배포, 데이터와의 근접성 등 특정 문제 해결에 뛰어나기 때문이다. 바뀐 것은 이들의 유효성이 아니라, 이제 더 풍부한 클라이언트 사이드 동작과 경쟁이 아닌 공존한다는 생각이다.

롤백이 아니라 아키텍처 지도 자체의 확장이다.

제약 조건에 따른 아키텍처

팀이 이념에서 벗어나기 시작하면 더 생산적인 대화가 가능해진다. 질문은 “최선의 모델은 무엇인가?”에서 “지금 우리가 무엇을 위해 최적화하는가?”로 바뀐다.

데이터 변동성은 중요하다. 일주일에 한 번 바뀌는 콘텐츠와 개인화된 실시간 데이터 스트림의 동작방식은 서로 매우 다르다. 성능 예산 역시 중요하다. 전자상거래 흐름에서는 100밀리초의 지연이 곧바로 매출 손실로 이어질 수 있는 반면 내부 관리용 툴에서는 이정도의 지연은 상관없을 것이다.

운영 현실도 영향을 미친다. 일단의 SSR 서버를 별 부담 없이 운영하고 관찰할 수 있는 팀도 있고, 인력 규모와 전문성에 따라 정적 우선 또는 서버리스 접근 방식이 더 적합한 팀도 있다.

이런 압력이 애플리케이션 전반에 균일하게 작용하는 경우는 거의 없다. 업타임 요구사항이 엄격한 시스템은 결합도와 장애 영향을 줄이기 위해 여러 계층에 걸쳐 로직을 중복시킬 수도 있다. 예를 들어 중요한 검증 규칙을 API 경계에서 적용하고 클라이언트에서도 다시 적용해서 하나의 백엔드 장애가 사용자 워크플로우를 완전히 차단하는 상황을 방지한다.

이 맥락에서 하이브리드 아키텍처는 더 이상 타협이 아니다. 절충이 우발적으로 일어나게 두는 것이 아니라, 명시적으로 드러나게 하는 방법이 된다.

UI에 대한 서버의 책임 증가

최근 몇 년 사이 나타난 미묘한 변화 하나는 브라우저가 상호작용 가능한 상태가 되기 전에 서버가 맡아 처리하는 일의 양이다.

이는 단순히 SEO 또는 더 빠른 첫 화면 표시에 그치지 않는다. 서버는 예측 가능한 환경에서 작동한다. 안정적인 CPU 리소스를 갖고 있으며 데이터베이스와 내부 서비스에 직접 액세스한다. 반면, 브라우저는 고성능 데스크톱부터 불안정한 네트워크의 저성능 모바일 디바이스에 이르기까지 매우 다양한 환경에서 실행된다.

무거운 작업을 서버에서 처리하는 경우가 점점 증가하고 있다. 단편화된 데이터를 클라이언트로 보내 브라우저가 조합하도록 요청하는 대신, 서버가 UI에 바로 사용할 수 있는 뷰 모델을 준비한다. 서버가 데이터를 집계하고 권한을 확인하고 상태를 만든다. 이런 작업을 클라이언트에서 반복적으로 수행한다면 비용이 많이 들거나 중복 작업이 될 것이다.

페이로드가 브라우저에 도달하는 시점이면 클라이언트의 역할은 더 좁아져서 활성화하고 강화하는 일을 하게 된다. 이로써 상호작용에 이르기까지의 시간이 단축되고 사용자에게 전달되는 변환 로직의 양이 줄어든다.

이는 자연스럽게 점진적이고 선택적인 하이드레이션으로 이어진다. 하이드레이션은 더 이상 양극단의 단계가 아니다. 중요한 상단 요소가 먼저 상호작용 가능해지고, 사용 빈도가 비교적 낮은 구성요소는 사용자가 실제로 손을 댈 때까지 하이드레이션되지 않을 수 있다.

이 모델에서 성능 최적화는 전역적이 아닌 국소적인 작업이 된다. 팀은 전체 애플리케이션을 재구성하지 않고도 특정 뷰나 워크플로우를 개선할 수 있다. 렌더링은 이분법적 선택이 아니라 단계적 과정이 된다.

디버깅 가능성에 따라 바뀌는 아키텍처 대화의 방향

애플리케이션이 더 분산될수록 아키텍처를 구성하는 요소에서 성능 외에 디버깅 가능성도 대등하게 중요한 요소가 된다.

비교적 단순한 시스템에서는 장애를 쉽게 추적할 수 있었다. 렌더링은 한 곳에서 발생했고 로그의 맥락은 명확했다. 현대 애플리케이션에서는 빌드 파이프라인, 엣지 런타임, 장기간 유지되는 클라이언트 세션에 걸쳐 렌더링이 분할될 수 있다. 데이터도 서로 다른 시점에 불러오고 캐시하고 변환하고 다시 하이드레이션된다.

많은 경우 뭔가 잘못됐을 때 가장 어려운 일은 고장이 발생한 위치를 알아내는 것이다.

단계적 아키텍처가 실질적 이점을 제공하는 영역이 바로 여기다. 렌더링 책임이 명확하면 장애는 대체로 더 국소화된다. 초기 렌더링 오작동은 서버 계층을 가리킨다. UI가 보기에는 정상인데 상호작용에서 실패한다면 하이드레이션이나 클라이언트 사이드 상태에 문제가 있다는 뜻이다. 아키텍처 수준에서 이는 개별 클래스를 넘어 적용되는 단일 책임 원칙과 비슷하다. 각 단계에는 명확한 변경의 이유, 그리고 문제 발생 시 조사해야 할 명확한 위치가 있다.

이런 복잡성을 “자동” 추상화 뒤에 숨기려고 시도하는 아키텍처는 많은 경우 디버깅을 오히려 더 어렵게 만든다. 엔지니어는 시스템 설계에 대해 추론하는 것이 아니라 프레임워크의 동작을 리버스 엔지니어링하는 상황에 처한다. 경험이 많은 팀이 매력적이지만 불투명한 시스템보다 지루하더라도 명시적인 시스템을 선호하는 것도 당연하다고 볼 수 있다.

프레임워크는 답이 아니라 답으로 향하는 길

생태계 전반에서 이 변화를 볼 수 있다. 앵귤러가 좋은 예다. 한때 무거운 클라이언트 사이드 개발을 대표했던 앵귤러는 서버 사이드 렌더링과 세분화된 하이드레이션 신호를 꾸준히 포용했다. 중요한 점은 앵귤러를 사용하는 하나의 방식을 강요하지 않는다는 것이다.

다른 곳에서도 이 패턴을 볼 수 있다. 현대 프레임워크는 더 이상 이념 전쟁에서 승리하려 애쓰지 않는다. 대신 작업이 수행되는 시점, 상태가 존재하는 위치, 그리고 시간 경과에 따른 렌더링 전개를 제어할 수 있는 이런저런 조정 수단을 제공한다.

경쟁의 관건은 더 이상 순수성이 아니라 현실적 제약 조건 하에서의 유연성이다. 순수 아키텍처는 그린필드 프로젝트에서는 좋아 보이는 경향이 있지만 시간이 갈수록 삐걱댄다.

요구사항은 늘 발전한다. 경직된 모델에는 그러한 요구사항의 발전에 따라 예외가 누적된다. 처음 시작할 때는 깔끔했던 규칙 집합이 어느새 단서 조항의 집합으로 변질된다. 복잡성을 초기에 인정하는 아키텍처는 대체로 회복탄력성이 뛰어나다. 명확한 경계를 통해 시스템의 다른 부분을 불안정하게 하지 않으면서 한 부분을 발전시킬 수 있다.

2026년 들어 엄격하다는 것은 동일성을 강제하는 것이 아니라 명확성을 강제하는 것이다. 즉, 코드가 어디에서 실행되는지, 거기서 실행되는 이유가 무엇인지, 그리고 장애가 어떻게 전파되는지를 아는 것이다.

스펙트럼 포용

웹을 구축하는 단 하나의 “올바른” 방법이 있다는 생각은 마침내 힘을 잃고 있다. 좋은 현상이다.

서버 사이드 렌더링과 클라이언트 사이드 애플리케이션은 애초에 상호 적대적 관계가 아니라, 각자 서로 다른 시점에서 서로 다른 문제를 해결하는 툴이었다. 대다수 아키텍처 질문에는 모든 상황에 통용되는 보편적 정답이 없다는 사실을 인정할 만큼 이제 웹은 성숙하다.

오늘날 가장 성공적인 팀은 유행을 쫓는 팀이 아니라 제약 조건을 이해하고 성능 예산을 존중하고 렌더링을 스위치가 아니라 스펙트럼으로 다루는 팀이다. 웹의 성장은 어느 한 편을 선택한 데 따른 결과가 아니라 차이를 포용한 결과이며, 아키텍처 역시 같은 방식을 택하는 아키텍처가 오래 살아남게 될 것이다.
dl-itworldkorea@foundryco.com

관련자료

댓글 0
등록된 댓글이 없습니다.
Member Rank