CSR, SSR, SSG 조화를 이루다. 은 Node.js 기반의 SSR 개발을 통해 겪은 경험기로 간단한 용어 설명 및 웹의 진화 과정에 대한 내용을 다룹니다.
위의 세 단어는 웹 서비스를 해보셨다면, 웹 개발자뿐만 아니더라도 한 번쯤은 들어봤을 법한 용어입니다. 간단하게 설명하면 다음과 같습니다.
SSG(Static-Site-Generation)
다른 말로, Static-Rendering 이라고도 하는 해당 방식은 클라이언트에서 필요한 페이지들을 사전에 미리 준비해뒀다가, 요청을 받으면 이미 완성된 파일을 단순히 반환하여 브라우저에서 뷰를 보여지게 됩니다.
SSR(Server-Side-Rendering)
서버에서 뷰 구성에 필요한 전체 HTML을 요청을 받은 즉시 생성해서 반환합니다. 이렇게 하면 클라이언트 브라우저에서 응답을 받은 후, 이미 완성된 뷰를 그대로 보여지게 됩니다.
CSR(Client-Side-Rendering)
클라이언트 브라우저에서 어플리케이션을 렌더링을 진행합니다. 즉 어플리케이션 구동에 필요한 HTML, JS, CSS 파일 등을 모두 다운로드 한 뒤에 뷰가 구성되게 됩니다.
웹의 발전 과정
팀 버너스리에 의해 World-Wide-Web이 개발, 인터넷이라는 개념이 등장하고 나서 웹은 다음과 같은 발전 과정을 거쳤습니다.
초기 웹은 대다수가 SSG 방식의 정적 웹으로 제공되고 있었습니다. 고사양 컴퓨터도 보편화되지 않았을뿐더러, 단순히 정보를 제공하는 정도였기 때문에, 특별한 기능이 많지 않았고, 복잡한 UI도 많이 요구되지 않았습니다.
하지만 시간이 지나면서 사용자간의 상호작용이 중요해짐에 따라서 사용자 뷰를 동적으로 보여줄 수 있는 Javascript 중심의 개발이 진행되면서 동적으로 HTML 태그를 생성하게 되는 SPA(Single-Page-Application) 개념이 등장하게 됩니다.
우리가 사용하는 React, Vue, Angular가 전부 SPA 개념을 사용하고 있죠. 그렇다면, 현재 웹 서비스는 전부 CSR으로만 동작하고 있을까요? 아닙니다. 아주 큰 문제가 발생하죠.
각 Rendering 방식의 단점
CSR 방식의 단점
초기 Javascript 파일을 전부 로드한 후, 뷰를 구성해야하기 때문에 어플리케이션이 커질수록 구동시간이 점점 느려집니다.
마찬가지로 Javascript 파일을 전부 로드해야, 페이지 정보를 구성할 수 있으므로 SEO(Search-Engine-Optimization)에도 취약한 문제가 있습니다.
초기 사이트 진입 시간이 사용자의 이탈률에 크게 영향이 있는 만큼 PWA(Progressive-Web-App)이 아닌 이상, 치명적인 단점입니다. IE를 지원하기 위해 필요한 polyfill 자원까지 포함된다면 상상만 해도 골치 아픕니다.
물론 Code-Splitting을 사용하여 어느 정도 해결할 수는 있겠지만, SEO 문제까지 해결할 수는 없어 보입니다. 그럼 SSR은 어떨까요?
SSR 방식의 단점
페이지 전환 간에 깜빡임 현상이 존재합니다. 페이지를 이동할 때마다, 서버에서 렌더링해주는 새로운 파일을 받기 때문이죠.
새로운 파일을 받아서 다시 필요한 파일을 로드하는 것이기 때문에, 클라이언트단에서 메모리에 데이터를 유지할 수가 없습니다. 이는 SSG 방식도 마찬가지입니다.
물론, SEO 문제는 해결할 수 있지만, SSR 방식으로만 어플리케이션을 구성하기에는 사용자가 늘어날수록 서버의 부하가 점점 커지기도 하더러, 사용자 경험적으로도 한계가 존재하는 방식이라고 생각이 듭니다.
SSG 방식의 단점
이미 Pre-rendering된 정적 파일이 있으므로, 서버에서는 단지 그 파일을 클라이언트로 전달해줄 뿐이어서 정말 빠릅니다. 그렇지만, 웹 서비스에 존재하는 수많은 페이지들을 전부 정적 파일로 만들어주기에는 현실적으로 무리가 있어 보입니다.
그렇다면 우리는 대체 어떤 전략을 택해야 할까요? 😟
조화를 이뤄보자
우리는 어느 하나의 렌더링 전략을 택해서는 계속 하나씩 문제가 발생한다는 것을 알 수 있습니다. 그렇기에 현재 본인도 사용 중인 Next.js 에서도 사용하는 방식처럼 여러 전략을 조화롭게 사용해야 합니다.
초기 렌더링과 이후 렌더링을 나눠보자
각 렌더링 방식을 잘 파악하고 있다면 우리는 다음과 같이 해결방법을 생각할 수 있습니다.
첫 방문 시에는 로드 속도가 빠르고 SEO까지 가져갈 수 있는 SSR 또는 SSG 방식, 페이지가 한 번 로드된 이 후에는 사용자경험을 가져갈 수 있는 CSR 방식을 선택
그럼 어느 상황일 때, SSR을 쓰며, SSG 방식을 적용해야할까요?
상황에 맞는 Pre-rendering
쇼핑몰 사이트를 예시로 들어보겠습니다.
쇼핑몰의 각 상품에 대한 정보는 잘 바뀌지 않는 데이터라고 가정합니다.
이럴 때, 우리는 각 상품에 관한 페이지들을 미리 Pre-rendering 하여 페이지를 만들어둡니다. 이렇게 되면 클라이언트가 상품 페이지를 요청할 때, 서버는 단지 파일을 내려주기만 하면 될 뿐입니다! - SSG
그렇지만, 만약 해당 페이지에 존재하는 핵심 데이터가 수시로 바뀌는 데이터라면? 여기에 SEO까지 함께 가져가야 한다면? SSR 방식을 택하는 게 효율적일 겁니다. - SSR
SEO가 딱히 중요하지 않고, 수시로 바뀌는 데이터라면 SSR을 할 것까지도 없습니다. 오히려 서버 연산 비용증가로 사용자가 증가함에 따라서 상당한 계산 오버헤드가 발생할 수도 있습니다.
속도를 더 빠르게?
TTFB(Time to First Byte) 속도를 더 빠르게 하기 위해서 Pre-rendering된 HTML 파일을 CDN을 사용하는 방법도 있습니다.
다만, cloudflare은 오히려 TTFB에 악영향을 준다고 합니다. 적용하기 전에 항상 테스트를 해보고 적용하는 것을 권장드립니다.
추가로, 아래 사진은 Google Developers에서 올린 Server - Client 스펙트럼을 보여주고 있으며, 자신의 서비스가 어떤 상황인지 파악하고 각 상황에 맞는 전략을 택하면 좋을 것 같습니다.