들어가며
웹페이지를 응답하는 방식이 발전한 흐름과 현대적인 방식인 SSR, CSR, 그리고 Universal Rendering 방식에 대해 알아보자.
웹페이지를 응답하는 방식의 발전
초창기 웹 애플리케이션은 웹페이지를 통해 텍스트 중심의 단순한 문서를 제공했다.
그래서 페이지마다 각각 다른 웹페이지를 만들어놓고 서버에 저장해두었다. 이를 MPA(Multi Page Application)이라고 부른다.
따라서 사용자가 웹페이지를 서버로 요청할 때마다 매번 새로운 페이지를 응답받게 되고, 이로 인해 페이지를 이동할 때마다 화면이 깜빡이면서 전혀 새로운 페이지를 브라우저에 그려야 했다.
점점 웹페이지에 사진, 동영상 등이 많이 추가됨에 따라 기존 방식으로는 속도가 느리다는 문제가 있었다.
이를 개선하기 위해 Ajax 라는 기술이 탄생했다. 이 기술을 통해 필요한 부분만 리로드할 수 있게 되었다.
이 기술이 발전하면서 SPA(Single Page Application) 방식의 웹페이지가 탄생했다.
SPA는 웹페이지를 하나만 만들어놓고, 변경될 부분에 대해서만 데이터를 요청하고 재렌더링하는 기술이다.
여기서 MPA 방식이 현재 Server Side Rendering이라고 불리는 SSR 방식이 채택한 방법이고, SPA 방식은 Client Side Rendering이라고 부르는 CSR 방식이 채택한 방식이다.
즉, SSR은 사용자가 요청하는 웹페이지를 서버에서 렌더링하여 응답하는 구조이고, CSR은 클라이언트(브라우저)가 하나의 웹페이지를 받아서 변경이 필요한 부분만 재렌더링하는 방식이다.
렌더링을 처리하는 주체가 누구냐에 따른 방법의 차이이다.
CSR (Client Side Rendering)
사용자의 첫 요청에 비어있는 HTML 파일 하나 전달한다. 이 HTML 파일을 통해 필요한 CSS와 JavaScript 파일을 불러올 수 있다.
불러온 파일들을 모두 이용하여 웹페이지를 브라우저 상에서 처리하는 구조이다.
이러한 방식으로 인해, 요청을 보내고 첫 응답이 오기까지는 매우 적은 시간이 걸리지만, 결국 웹페이지 내의 유의미한 콘텐츠를 보기까지의 시간 조금 걸린다.
또한, CSR은 검색 결과 노출에 약하다.
검색엔진 크롤러 봇이 정보를 수집하기 위해 웹사이트를 돌아 다닐 때, CSR 방식의 웹페이지인 경우 결국 JavaScript를 실행해야 유의미한 콘텐츠(글, 사진, 동영상 등)가 노출된다.
하지만 크롤러 봇은 JavaScript를 실행할 수 없는 환경이기 때문에 검색 엔진 최적화에 취약하다는 단점이 있다.
왜 크롤러 봇은 JavaScript를 실행할 수 없는 환경일까?
바로 비용과 효율성 문제 때문이다.
봇은 하루에 수십억 개의 페이지를 방문한다. 단순히 HTML 파일을 읽고 결과를 가져오는 것은 가벼운 CPU와 메모리로 가능하다.
하지만 JavaScript를 실행해서 렌더링하는 작업을 포함하면 많은 컴퓨팅 자원도 많이 필요할 뿐더러 시간도 오래 걸리기 때문에 비효율적이다.여담으로 GoogleBot의 경우 JavaScript를 실행할 수 있는 능력을 갖추긴 했지만, 기본적으로 수행하지 않거나 매우 제한적으로 렌더링을 수행한다.
SSR
사용자의 요청이 오면, 서버가 웹페이지 렌더링을 모두 마쳐 클라이언트(브라우저)에게 응답하는 방식이다.
사실은 여기에도 또 두 가지 방식으로 나뉜다.
하나는 요청이 오는 즉시 HTML 파일을 만들어서 응답하는 방식(SSR)이고, 또 하나는 미리 다 만들어놓은 정적 웹페이지를 응답하는 방식(SSG, Static Site Generation)이다.
SSR 방식의 경우 웹페이지에 필요한 동적 데이터를 HTML에 포함하기 위해 DB나 API 서버로부터 데이터를 가져와 HTML에 포함해서 클라이언트에게 응답을 하게 된다.
이때 중요한 점은, 아직 JavaScript가 실행되기 전이라는 점이다.
HTML이 완성되고 콘텐츠가 모두 보이더라도 JavaScript가 실행되기 전이므로 버튼을 누르더라도 동작하지 않는다.
브라우저는 응답받은 HTML을 화면에 보여주는 동시에 서버에 요청해서 필요한 JavaScript 파일을 다운로드 받는다.
파일이 로드되면 브라우저 환경에서 JavaScript가 실행되며, 기존 정적 HTML 구조에 이벤트 리스너를 달고 동적인 기능을 연결을 하는 하이드레이션(Hydration) 과정을 거친다.
이 과정이 끝나야만 비로소 사용자가 버튼을 클릭했을 때 동작하는, 상호작용 가능한 웹페이지가 완성되는 것이다.
SSR 방식의 경우 브라우저의 요청이 오면, 웹페이지에 필요한 콘텐츠를 모두 완성해놓은 정적 HTML을 브라우저로 응답한다고 했다.
따라서 CSR과 달리, 검색 엔진 최적화에 유리하다.
그리고 콘텐츠를 보여주는 속도가 CSR에 비해 빠르다. 비록, JavaScript가 동작하지 않는 정적 HTML인 순간이 있다하더라도 사용자에게는 콘텐츠를 미리 보여줌으로써 더 나은 사용자 경험을 제공할 수 있는 기회가 마련된다.
(이를 TTV(Time To View)가 빠르다고 한다.)
하지만 모든 기술이 그렇듯 완벽한 것은 아니다.
SSR 방식은 요청이 들어올 때마다 서버에서 HTML을 새롭게 생성해야 하기 때문에, 요청에 따른 서버 자원이 필요하다.
많은 요청이 오면 그만큼 많은 비용이 드는 것이다.
현대의 방식: 유니버셜 렌더링 (Universal Rendering)
최근에는 무조건적인 SSR보다는 웹페이지 성격에 따라 CSR을 섞어서 사용하는 추세이다.
서비스의 첫 진입 페이지나 상세 상품 페이지처럼 검색 엔진에 잘 걸려야 하는 페이지는 SSR을 사용하고, 관리자 페이지나 마이페이지처럼 로그인이 필요하거나 개인화된 기능이 많은 곳은 CSR을 사용하는 방식이다.
추가로 Next.js 프레임워크가 위 렌더링 방식을 지원한다.
참고
- 10분 테코톡 - 타미의 CSR과 SSR
- Gemini