levi

리바이's Tech Blog

Tech BlogPortfolioBoard
AllActivitiesJavascriptTypeScriptNetworkNext.jsReactWoowacourseAlgorithm
COPYRIGHT ⓒ eunwoo-levi
eunwoo1341@gmail.com

📚 목차

    [React] 서버 사이드 렌더링 (SSR)

    ByEunwoo
    2025년 4월 11일
    react

    최근에 Next.js Framwork가 인기를 끌면서 서버 사이드 렌더링(SSR)이라는 용어를 많이 들어봤을 것이다.

    서버 사이드 렌더링이 무엇인지 설명하기에 앞서 먼저 서버 사이드 렌더링 애플리케이션과 반대되는 개념인 싱글 페이지 애플리케이션에 대해 먼저 살펴보자.

    싱글 페이지 애플리케이션이란?

    싱글 페이지 애플리케이션(Single Page Application-SPA)이란 렌더링과 라우팅에 필요한 대부분의 기능을 서버가 아닌 브라우저의 자바스크립트에 의존하는 방식을 의미한다.
    최초에 첫 페이지에서 데이터를 모두 불러온 이후에는 페이지 전환을 위한 모든 작업이 자바스크립트와 브라우저의 history.pushstate와 history.replaceState로 이뤄지기 때문에 페이지를 불러온 이후에는 서버에서 HTML을 내려받지 않고 하나의 페이지에서 모든 작업을 처리하므로 싱글 페이지 애플리케이션이라고 한다.

    일반적으로 웹에서 볼 수 있는 싱글 페이지 애플리케이션의 HTML 코드를 크롬의 소스 보기로 캡처한 모습이다.
    이 사이트에 접속하면 전체 사이트를 모두 볼 수 있지만 실제로 소스 보기로 HTML 코드를 봤을 때는 <body/> 내부에 아무런 내용이 없다.
    이는 사이트 렌더링에 필요한 <body/> 내부의 내용을 모두 자바스크립트 코드로 삽입한 이후에 렌더 링하기 때문이다.
    또한, 페이지 전환 시에도 새로운 HTML 페이지를 요청하는 게 아니라 자바스크립트에서 다음 페이지의 렌더링에 필요한 정보만 HTTP 요청 등으로 가져온 다음, 그 결과를 바탕으로 내부에 DOM을 추가, 수정, 삭제하는 방법으로 페이지가 전환된다.

    즉, 최초에 서버에서 최소한의 데이터를 불러온 이후부터는 이미 가지고 있는 자바스크립트 리소스와 브라우저 API를 기반으로 모든 작동이 이뤄진다. 이러한 작동 방식은 최초에 로딩해야 할 자바스크립트 리소스가 커지는 단점이 있지만 한번 로딩된 이후에는 서버를 거쳐 필요한 리소스를 받아올 일이 적어지기 때문에 사용자에게 훌륭한 UI/UX를 제공한다는 장점이 있다.

    서버사이드 렌더링이란?

    싱글 페이지 애플리케이션이 자바스크립트를 활용해 하나의 페이지에서만 렌더링을 수행한다면, 서버 사이드 렌더링은 최초에 사용자에게 보여줄 페이지를 서버에서 렌더링해 빠르게 시용자에게 화면을 제공하는 방식을 의미한다.
    웹페이지가 점점 느려지는 상황에 대한 문제의식을 싱글 페이지 애플리케이션의 태생적인 한계에서 찾고, 이를 개선하고자 서버에서 페이지를 렌더링해 제공하는 기존 방식의 웹 개발이 다시금 떠오르고 있다.

    • 싱글 페이지 애플리케이션과 멀티 페이지 애플리케이션의 차이. 멀티 페이지 애플리케이션은 모든 페이지를 서버에서 요청받은 후에 완성된 HTML을 렌더링한다.

    즉, 싱글 페이지 애플리케이션과 서버에서 페이지를 빌드하는 서버 사이드 렌더링의 차이는 웹페이지 렌더링의 책임을 어디에 두느냐다.
    싱글 페이지 애플리케이션은 사용자에게 제공되는 자바스크립트 번들에서 렌더링을 담당하지만 서버 사이드 방식을 채택하면 렌더링에 필요한 작업을 모두 서버에서 수행한다.

    클라이언트의 렌더링은 사용자 기기의 성능에 영향을 받지만 서버 사이드 렌더링은 서버에서 제공하기 때문에 비교적 안정적인 렌더링이 가능하다

    서버 사이드 렌더링의 장점

    1. 최초 페이지 진입이 비교적 빠르다

    사용자가 최초 페이지에 진입했을 때 페이지에 유의미한 정보가 그려지는 시간(First Contentful Paint)이 더 빨라질 수 있다. 최초에 사용자에게 보여줘야 할 화면에 표시할 정보가 외부 API 호출에 많이 의지해야 한다고 가정해 보자.

    싱글 페이지 애플리케이션이라면 사용자가 해당 페이지에 진입하고, 자바스크립트 리소스를 다운로드하고, HTTP 요청을 수행한 이후에 이 응답의 결과를 가지고 화면을 렌더링해야 할 것이다.
    그러나 이러한 작업이 서버에서 이뤄진다면 한결 빠르게 렌더링될 수 있다.
    일반적으로 서버에서 HTTP 요청을 수행하는 것이 더 빠르고, 또 HTML을 그리는 작업도 서버에서 해당 HTML을 문자열로 미리 그려서 내려주는 것이 클라이언트에서 기존 HTML에 삽입하는 것보다 더 빠르기 때문이다.

    모든 경우에 서버 사이드 렌더링이 초기 페이지 렌더링에 비해 이점을 가진다고 볼 수 없지만 화면 렌더링이 HTTP 요청에 의존적이거나 렌더링해야 할 HTML의 크기가 커진다면 상대적으로 서버 사이드 렌더링이 더 빠를 수 있다.

    물론 이것은 서버가 사용자에게 렌더링을 제공할 수 있을 정도의 충분한 리소스가 확보돼 있다는 일반적인 가정하에 비교한 것이다.
    서버가 사용자를 감당하지 못하고, 리소스를 확보하기 어렵다면 오히려 싱글 페이지 애플리케이션보다 느려질 수도 있다.

    2. 검색 엔진과 SNS 공유 등 메타데이터 제공이 쉽다

    서버 사이드 렌더링은 검색 엔진 최적화에 유용하다.
    왜 서버 사이드 렌더링이 검색 엔진 최적화에 유용한지
    이해하려면 먼저 검색 엔진이 사이트에서 필요한 정보를 가져가는 과정을 알아야 한다.

      1. 검색 엔진 로봇(머신)이 페이지에 진입한다.
      1. 페이지가 HTML 정보를 제공해 로봇이 이 HTML을 다운로드핸다. 단, 다운로드만 하고 자바스크립트 코드는 실행하지 않는다.
      1. 다운로드한 HTML 페이지 내부의 오픈 그래프(Open Graph)나 메타(meta) 태그 정보를 기반으로 페이지의 검색(공유)정보를 가져오고 이를 바탕으로 검색 엔진에 저장한다.

    이 검색 엔진의 페이지 방문과 사용자의 브라우저를 이용한 페이지 방문의 큰 차이점은 페이지 내부에 있는 자바스크립트 코드의 실행 여부다.
    브라우저는 해당 페이지를 사용자에게 HTML이나 각종 정보로 제공하기 위해 자바스크립트를 실행해야 하지만 로봇은 페이지를 보는 것이 아닌 페이지의 정적인 정보를 가져오는 것이 목적이므로 자바스크립트를 다운로드하거나 실행할 필요가 없다.

    싱글 페이지 애플리케이션은 대부분의 작동이 자바스크립트에 의존하는데, 이러한 메타 정보 또한 마찬가지다.
    검색 엔진이 최초에 방문했을 때, 즉 페이지에 최초로 진입했을 때 이러한 메타 정보를 제공할 수 있도록 조치를 취하지 않는다면 검색 엔진이나 SNS 공유 시에 불이익이 있을 수 있다.
    반면 서버 사이드 렌더링은 최초의 렌더링 작업이 서버에서 일어난다.
    즉, 검색 엔진에 제공할 정보를 서버에서 가공해서 HTML 응답으로 제공할 수 있으므로 검색 엔진 최적화에 대응하기가 매우 용이하다

    3. 누적 레이아웃 이동이 적다

    서버 사이드 렌더링은 누적 레이아웃 이동(Cumulative Layout Shift)을 줄일 수 있다.
    누적 레이아웃 이동이란 사용자에게 페이지를 보여준 이후에 뒤늦게 어떤 HTML 정보가 추가되거나 삭제되어 마치 화면이 덜컥거리는 것과 같은 부정적인 사용자 경험을 말한다.
    즉, 사용자가 예상치 못한 시점에서 페이지가 변경되어 불편을 초래하는 것을 말한다.

    신문 기사를 제공하는 사이트를 예로 들어보자. 화면 전체에 기사 내용이 있고, 중간에 가로로 긴 배너를 삽입하고자 한다.
    그런데 기사(글)의 로딩은 빨리 이뤄져서 화면에 먼저 노출되고 있는데, 갑작스럽게 뒤늦게 배너가 로딩된다면 어떻게 될까? 배너의 크기만큼 글 영역이 밀리면서 사용자에게 불편을 초래할 것이다.
    싱글 페이지 애플리케이션에서는 페이지 콘텐츠가 API 요청에 의존하고, API 요청의 응답 속도가 제각각이며, 이를 적절히 처리해두지 않는다면 이러한 누적 레이아웃 이동 문제가 발생할 수 있다.
    반면 서버 사이드 렌더링의 경우에는 이러한 요청이 완전히 완료된 이후에 완성된 페이지를 제공하므로 이러한 문제에서 비교적 자유롭다.

    4. 사용자의 디바이스 성능에 비교적 자유롭다

    서버 사이드 렌더링은 비교적 사용자 디바이스의 성능으로부터 자유롭다. 자바스크립트 리소스 실행은 사용자의 디바이스에서만 실행되므로 절대적으로 사용자 디바이스 성능에 의존적이다.
    그러나 서버사이드 렌더링을 수행하면 이러한 부담을 서버에 나눌 수 있으므로 사용자의 디바이스 성능으로부터 조금 더 자유로워질 수 있다. 물론 이 또한 절대적인 것은 아니다. 인터넷 속도가 느리다면 어떠한 방법론을 쓰든 느릴 것이고 사용자 방문이 폭증해 서버에 부담이 가중된다면, 그리고 이를 위한 적절한 처리가 수반돼 있지 않다면 서버 사이드 렌더링도 충분히 느려질 수 있다.

    5. 보안에 좀 더 안전하다

    프런트엔드 개발자라면 모두가 알겠지만 브라우저의 개발자 도구를 사용하면 웹사이트에서 일어나는 거의 대부분의 작업을 파악할 수 있다.
    이 작업에는 API 호출과 인증 같이 사용자에게 노출되면 안 되는 민감한 작업도 포함되므로 정상적인 비즈니스 로직을 거치지 않은 상황에서 인증이나 API가 호출되는 것을 항상 방지할 준비가 돼 있어야 한다.
    반면 서버 사이드 렌더링의 경우 인증 혹은 민감한 작업을 서버에서 수행하고 그 결과만 브라우저에 제공해 이러한 보안 위협을 피할 수 있다는 장점이 있다

    서버 사이드 렌더링의 단점

    1. 소스코드를 작성할 때 항상 서버를 고려해야 한다

    서버 사이드 렌더링을 적용하기로 결정했다면 소스코드 전반에 걸쳐 서버 환경에 대한 고려가 필요하다. 그중 가장 큰 문제가 바로 브라우저 전역 객체인 window 또는 sessionstorage와 같이 브라우저에만 있는 전역 객체 등이다.
    소스코드나 사용 중인 라이브러리에서 window를 사용하고 있고, 이 코드가 만약 서버에서 실행 된다면 'window is not defined’라는 에러를마주하게 된다.
    그러므로 서버에서도 실행될 가능성이 있는 코드라면 window에 대한 접근을 최소화해야 하고, window 사용이 불가피하다면 해당 코드가 서버 사이드에서 실행되지 않도록 처리해야 한다.

    2. 적절한 서버가 구축돼 있어야 한다

    싱글 페이지 애플리케이션이나 정적인 HTML 페이지만으로 서비스할 수 있는 웹페이지 경우에는 단순히 HTML과 자바스크립트, CSS 리소스를 다운로드할 수 있는 준비만 하면 된다. 서버는 정적인 데이터인 자바스크립트와 HTML을 제공하면 모든 역할이 끝난다.
    그러나 서버 사이드 렌더링은 말 그대로 사용자의 요청을 받아 렌더링을 수행할 서버가 필요하다. 그러나 서버를 구축하는 것은 절대 쉬운 일이 아니다.
    사용자의 요청에 따라 적절하게 대응할 수 있는 물리적인 가용량을 확보해야 하고, 때로는 예기치 않은 장애 상황에 대응할 수 있도록 복구 전략도 필요하다. 또한 요청을 분산시키고, 프로세스가 예기치 못하게 다운될 때를 대비해 PM26와 같은 프로세스 매니저의 도움도 필요하다.
    실제로 프로덕션 서버 사이드 렌더링 애플리케이션을 운영해 본 경험이 있다면 쿠버네티스 같은 여러 가지 라이브러리와 도구의 도움을 얻더라도 절대 쉽지 않은 일이라는 것을 알 것이다.

    3. 서비스 지연에 따른 문제

    예를 들어, 싱글 페이지 애플리케이션에서 무언가 느린 작업이 있다고 해보자.
    싱글 페이지 애플리케이션은 그래도 최초에 어떤 화면이라도 보여준 상태에서 무언가 느린 작업이 수행되기 때문에 ‘로딩 중’과 같이 작업이 진행 중임을 적절히 안내한다면 충분히 사용자가 기다릴 여지가 있다.

    반면 서버 사이드 렌더링에서 지연이 일어나면 어떻게 될까? 특히 이 지연 작업이 최초 렌더링에 발생한다면 큰 문제가 된다. 서버 사이드 렌더링은 서버에서 사용자에게 보여줄 페이지에 대한 렌더링 작업이 끝나기까지는 사용자에게 그 어떤 정보도 제공할 수 없다.
    애플리케이션의 규모가 커지고 작업이 복잡해지고, 이에 따라 다양한 요청에 얽혀있어 병목 현상이 심해진다면 때로는 서버 사이드 렌더링이 더 안 좋은 사용자 경험을 제공할 수도 있다

    싱글 페이지 애플리케이션과 서버 사이드 렌더링 애플리케이션 관점

    싱글 페이지 애플리케이션

    가장 뛰어난 싱글 페이지 애플리케이션은 가장 뛰어난 멀티 페이지 애플리케이션보다 낫다.
    Gmail과 같이 완성도가 매우 뛰어난 싱글 페이지 애플리케이션이 있다고 가정해 보자. 최초 페이지 진입 시에 보여줘야
    할 정보만 최적화해 요청해서 렌더링하고、이미지와 같은 중요성이 떨어자는 리소스는 게으른 로딩으로 렌더링에 방해되지 않도록 처리했으며, 코드 분할(code flitting, 사용자에게 필요한 코드만 나눠서 번들링하는 기법) 또한 칼같이 지켜서 불필요한 자바스크립트 리소스의 다운로드 및 실행을 방지했다.
    라우팅이 발생하면 변경이 필요한 HTML 영역만 교체해 사용자의 피로감을 최소화했다. 모든 것이 완벽하다. 멀티 페이지 애플리케이션 또한 마찬가지로 엄청난 최적화를 가미했다 하더라도 싱글 페이지 애플리케이션이 가진 브라우저 AF기와 자바스크립트를 활용한 라우팅을 기반으로 한 매끄러운 라우팅보다 뛰어난 성능을 보여줄 수는 없을 것이다.

    서버 사이드 렌더링 애플리케이션

    평균적인 싱글 페이지 애플리케이션은 평균적인 멀티 페이지 애플리케이션보다 느리다.
    멀티 페이지 애플리케이션은 매번 서버에 렌더링 요청을 하고, 서버는 안정적인 리소스를 기반으로 매 요청마다 비슷한 성능의 렌더링을 수행할 것이다. 그러나 일반적인 싱글 페이지 애플리케이션은 렌더링과 라우팅에 최적화가 돼 있지 않다면 사용자 기기에 따라 성능이 들쑥 날쑥하고 적절한 성능 최적화도 돼 있지 않을 가능성이 높으므로 멀티 페이지 애플리케이션 대비 성능이 아쉬울 가능성이 크다.
    그리고 이러한 최적화는 매우 어렵다. 페이지 전환 시에 필요한 리소스와 공통으로 사용하는 리소스로 분류하고 이에 따른 다운로드나 렌더링 우선순위 전략을 잘 수립해 서비스하기란 매우 어렵다. 따라서 평균적인 노력을 기울여서 동일한 서비스를 만든다면 서버에서 렌더링되는 멀티 페이지 애플리케이션이 더 우위에 있을 수 있다.
    심지어 최근에는 멀티 페이지 애플리케이션에서 발생하는 라우팅으로 인한 문제를 해결하기 위한 다양한 API가 브라우저에 추가되고 있다.

    결국 우리는 앞의 두 방법론이 모두 상황에 따라 유효한 방법이라는 것을 먼저 이해해야 한다. 두 가지 모두 장단점이 있으며 어느 하나가 완벽하다고 볼 수 없다. 싱글 페이지 애플리케이션이 제공하는 보일러플레이트나 라이브러리가 점차 완벽해지면서 잠재적인 모든 위험을 제거할 수도 있고, 멀티 페이지 애플리케이션이 브라우저 API의 도움을 받아 싱글 페이지 애플리케이션과 같은 끊김 없는 사용자 경험을 제공할 수도 있다.

    현대의 서버 사이드 렌더링

    현대의 서버 사이드 렌더링은 지금까지 LAMP 스택에서 표현했던 서버 사이드 렌더링 방식과는 조금 다르다.
    먼저 기존 LAMP 스택은 모든 페이지 빌드를 서버에서 렌더링해 초기 페이지 진입이 빠르다는 장점이 있지만 이후에 라우팅이 발생할 때도 마찬가지로 서버에 의존해야 하기 때문에 싱글 페이지 렌더링 방식에 비해 라우팅이 느리다는 단점이 있다.
    그래서 요즘의 서버 사이드 렌더링은 이 두 가지 장점을 모두 취한 방식으로 작동한다.
    먼저, 최초 웹사이트 진입 시에는 서버 사이드 렌더링 방식으로 서버에서 완성된 HTML을 제공받고, 이후 라우팅에서는 서버에서 내려받은 자바스크립트를 바탕으로 마치 싱글 페이지 애플리케이션처럼 작동한다.
    앞으로 살펴볼 Next.js, 그리고 Remix11 등 요즘 각광받는 서버 사이드 렌더링 프레임워크는 모두 이러한 방식으로 작동해 사용자에게 더 나은 웹사이트 경험을 안겨준다.
    이러한 라우팅과 렌더링 방식을 이해하지 못하면 모든 페이지에서 서버 사이드 렌더링으로 작동하는 LAMP 스택과 다름없는 멀티 페이지 애플리케이션을 만들어버릴 수도, 혹은 서버에서 아무런 작동도 하지 않는 싱글 페이지 애플리케이션 방식의 잘못된 웹서비스를 만들어 버릴 수도 있다.
    따라서 프런트엔드 개발자는 서버에서의 렌더링, 그리고 클라이언트에서의 렌더링을 모두 이해해야 두 가지 장점을 완벽하게 취하는 제대로 된 웹서비스를 구축할 수 있다.

    정리

    지금까지 서버 사이드 렌더링은무엇이고, 또 어떠한 장단점이 있는지 살펴봤다. 리액트 개발자라면, 특히 다수의 사용자에게 좋은 사용자 경험을 제공할 수 있는 웹 애플리케이션을 만들고 싶은 개발자라면 두 가지 방법을 모두 숙지할 필요가 있다.
    둘 중 어느 것이 완벽하게 옳다고 말할 수 없으므로 두 가지 모두를 이해하고 필요에 따라 맞는 방법을 사용할 수 있다.

    Posted inreact
    Written byEunwoo