Universal Server Side Rendering이란?

    Universal Server Side Rendering이란?


    이번 포스팅에서는 최근 모던 웹 어플리케이션에서 많이 사용하고 있는 Universal SSR에 대해서 설명하고자 한다. Server Side RenderingSingle Page Application의 방식을 간단하게 알아보고 이 두 렌더 방식을 조합한 Universal SSR의 방식을 설명한다.

    Server Side Rendering을 수행하는 Multi Page Application

    SSR 방식은 원래 전통적인 웹 어플리케이션에서 사용하던 방식이다. 최근에는 SPA(Single Page Application)과 대조하여 MPA(Multi Page Application)이라고도 불린다. SSR 어플리케이션은 라우팅이 수행된 후 새로운 페이지가 서버에 요청되면 싶으면 그때마다 HTML를 렌더한 후 클라이언트에서 전체 페이지를 다시 내려받는다.

    대략적인 실행 순서는 다음과 같다.

    ssr

    1. 클라이언트가 서버에 example.com/products/12 URL로 요청을 보낸다.
    2. 서버에서는 해당 URL과 연결되어있는 메소드가 실행되고 알맞는 HTML Template파일을 찾는다.
    3. Database에서 12번 상품의 데이터를 가져온다.
    4. 가져온 데이터와 HTML Template을 사용해 최종 HTML을 렌더한다.
    5. 클라이언트로 HTML을 내려준다.
    6. 최종적으로 사용자가 뷰를 본다.

    사용자가 렌더된 페이지를 본 이후에도 Ajax를 사용하여 데이터를 추가로 더 받아올 수도 있겠지만 일단 사용자가 완성된 페이지를 보는 시점은 6번 과정이 끝난 이후기 때문에 Ajax와 같은 예외는 생략했다.

    또한 2번 과정에서 어째서 이 방식의 어플리케이션이 MPA라고 불리는 지 알 수 있는데, 각 페이지에 매칭된 HTML Template이 따로 존재하기 때문이다. 다음과 같은 방식의 장단점은 다음과 같다.

    장점

    • 서버에서 완성된 HTML을 내려주기 때문에 SEO(Search Engine Optimization)에 최적화되어 있다.
    • 매 페이지에서 필요한 리소스만 로딩하기 때문에 초기 로딩속도를 최적화할 수 있다.

    단점

    • 매 페이지 로딩 시마다 새로운 리소스를 요청해야하므로 전체적인 트래픽이 증가한다.
    • 페이지 이동 시 마다 새로고침이 되며 전체 페이지를 다시 렌더하므로 로딩 시간이 길어진다.

    Client Side Rendering을 수행하는 Single Page Application

    최근 들어 많은 수의 Frontend 개발자가 Client Side Rendering을 수행하는 A.K.A SPA(Single Page Application)를 개발한다. 즉, 서버에서 실제로 다운로드 받는 페이지는 단 1개이고 그 이후 JavaScript를 통해 동적인 렌더링을 실시하는 어플리케이션을 의미한다.

    대략적인 실행 순서는 다음과 같다.

    csr

    1. 클라이언트가 서버에 example.com/products/12 URL로 요청을 보낸다.
    2. 서버에서는 뭐가 됐던 요청 URL이 exmplate.com으로 시작하면 index.html을 찾아서 내려준다.
    3. 그리고 추가로 JavaScript Bundle을 같이 내려준다. 예를 들면 Webpack같은 모듈러로 빌드하면 나오는 bundle.js같은 파일이 되겠다.
    4. bundle.js을 실행한 클라이언트가 api.example.com/products/12 API를 사용하여 12번 상품의 데이터를 서버에 요청한다.
    5. 서버는 Database에서 12번 상품의 데이터를 가져온 후 클라이언트에 데이터를 내려준다.
    6. 클라이언트는 받아온 데이터를 사용하여 뷰가 렌더한다.
    7. 최종적으로 사용자가 뷰를 본다.

    아까에 비해서 뭔가 복잡해졌다. 이 방식이 SPA인 이유는 2번 과정에 있다. 보통 NginxApache같은 서버 엔진의 설정에 해당 url을 선언하고 조건에 일치하는 url로 요청이 들어왔을 경우 index.html파일을 찾아서 보내준다. 어떤 url이든 조건에 일치하게 되면 index.html 하나만 보내주기 때문에 Single Page인 것이다.

    그리고 클라이언트는 현재 12번 상품의 데이터를 가지고 있지 않기 때문에 추가적으로 API 호출을 하여 12번 상품의 데이터를 받아와야 한다.

    그럼 SPA의 장단점도 한번 살펴보자.

    장점

    • 초기 로딩 시 서버로부터 모든 정적 리소스를 내려받은 후에는 페이지 이동 시 필요한 데이터만 내려받으므로 로딩 속도가 빠르고 전체적인 트래픽을 감소시킬 수 있다.
    • 페이지 이동 시 새로고침이 되지 않으므로 사용자 경험(UX)가 향상된다.

    단점

    • 초기 로딩 시 현재 페이지에서 사용하지않는 모든 정적 리소스를 받으므로 초기 로딩속도가 느리다.
    • SEO에 취약하다.

    SSR vs SPA

    각 방식의 대략적인 실행 흐름과 장단점을 살펴보았는데, SSRSPA 두 방식 모두 로딩 속도라는 장단점을 가지고 있다. 뭐가 다른 걸까?

    SSR의 장점은 초기 로딩속도이다. SPA는 첫 로딩 시 전체 어플리케이션에서 사용하는 모든 정적 리소스를 내려받기 때문에 초기 로딩속도는 느리지만 그 이후에는 추가적으로 리소스를 다운로드 받을 필요가 없기 때문에 이후 구동 속도가 빠른 것이다.

    반면 SSR은 현재 페이지에서 필요한 리소스만 로딩하면 되기 때문에 초기 로딩속도는 SPA에 비해서 빠를 수 있다. 그러나 받아온 정적 리소스를 어딘가에 저장하고 있는 게 아니기 때문에 페이지를 이동할때마다 저번 페이지에서 받아왔던 리소스라고 하더라도 처음부터 다시 받아와야한다.

    그래서 어플리케이션 초기화 후 페이지 이동 시 로딩 시간은 SSR이 더 느릴 수 있다.

    하지만 SPA방식의 어마무시한 단점은 바로 SEO다. SEO는 Search Engine Optimization의 약자로 직역 그대로 검색엔진최적화를 의미한다.

    검색 엔진은 기본적으로 크롤링을 해서 페이지를 수집하는 방식으로 이루어져있는데, 문제는 크롤링을 하는 봇들이 JavaScript를 실행할 수 있는 능력이 없다는 것이다.

    최근 구글 크롤러 같은 경우는 JavaScript 실행능력이 있다고 하지만 개인적으로 아직까지 그렇게까지 신뢰가 가는 정도는 아니라고 본다. 게다가 Facebook과 같은 SNS에 페이지 공유를 했을때에는 og meta tag를 크롤러가 읽어야지 공유된 사이트의 정보가 올바르게 표시되는데, JavaScript가 실행되지 않은 페이지를 크롤러가 읽었을 때는 그냥 빈페이지밖에 없으니 정보를 제대로 표시해주지 못하는 문제도 있었다.

    필자도 이 문제를 해결하기 위해 #!(해쉬뱅)이라던가 _esacped_fragment_이러단가 Pre rendering 같은 방법들을 사용해봤었지만 검색엔진사에서 권장하는대로 어플리케이션을 작성해도 SSR방식에 비해 데이터를 제대로 못긁어가는 건 어쩔 수 없었다.

    새로운 개념의 Server Side Rendering의 등장

    SSR을 택하자니 SPA의 장점이 아깝고, SPA를 택하자니 SSR의 장점이 아깝다. 그럼 어떻게 해야할까? 그래서 나온 방식이 최근에 많이 사용하고 있는 두 방식을 적당히 짬뽕한 방식이다. 사용자의 첫 요청시에만 SSR을 수행하고, 그 이후는 SPA처럼 동적인 렌더링을 수행하는 것이다. 이 방식은 아래와 같은 장점을 가진다.

    장점


    1. 첫 요청을 SSR로 완성된 HTML을 내려줌으로써 SEO와 초기 렌더링 속도문제를 해결
    2. 이후 클라이언트에서 렌더링을 수행함으로써 SPA의 장점인 페이지 이동 시 빠른 렌더 속도도 그대로 가져감
    3. Frontend 프레임워크 3대장인 Angular, React, Vue 모두 이러한 SSR 방식을 공식으로 지원하기 때문에 Client와 Server를 같은 Context로 묶을 수 있음. 즉, 내가 만든 컴포넌트는 클라이언트에서 렌더를 수행하든 서버에서 렌더를 수행하든 동일하게 실행된다.

    하지만 모든 기술에는 Trade-off가 있는 법…단점은 뭐가 있을까?

    단점


    1. 코드가 복잡하다. 어플리케이션 구동 순서를 확실하게 파악하고 있지 않다면 진짜 헷갈린다.
    2. 서버에서 렌더링을 수행하므로 단순 리소스 서빙보다는 아무래도 CPU를 많이 사용하게 되고, 부하가 걸릴 수 있다.
    3. 서버에 익숙하지 않은 Frontend 개발자의 경우 클라이언트처럼 개발을 진행하게 되면 의도하지 않은 버그가 생길 수 있다.

    특히 2번과 3번 같은 경우 필자가 간과했던 부분인데, 클라이언트에서는 아무 문제 없었을 부분이 서버에서는 치명적인 실수가 되어 버그로 돌아오는 경험을 했다.

    다음 포스팅에서는 필자가 회사에 Vue-ssr을 도입했던 경험과 어떤 실수를 했는지에 대해서 적어보고 회고하려고 한다.

    이상으로 Universal Server Side Rendering이란? 포스팅을 마친다.

    Evan Moon

    🐢 거북이처럼 살자

    개발을 잘하기 위해서가 아닌 개발을 즐기기 위해 노력하는 개발자입니다. 사소한 생각 정리부터 튜토리얼, 삽질기 정도를 주로 끄적이고 있습니다.