프론트 엔드 분야는 React나 Vue를 이용한 SPA가 가장 유명합니다. 그러나 프론트 엔드 분야를 처음 접하면 CSR(Client Side Rendering)과 SSR(Server Side Rendering)이라는 용어도 함께 접해 본적이 있을 것입니다. 각각의 방식은 최초의 DOM tree가 어디서 생성되느냐에 따라 구분 지은 것입니다.

Client Side Rendering(CSR)

CSR은 브라우저에게 도구(JS)를 주고 직접 DOM tree를 그리게 합니다. 출처: Copilot

CSR은 서버에서 JS파일을 가져와 브라우저(Client)가 화면을 그리는(Render)방식을 뜻합니다. CSR은 초기 로드 시 클라이언트는 빈 HTML 페이지를 받고, JavaScript를 사용하여 필요한 DOM element를 구성하여 화면에 렌더링합니다. 이로 인해 초기 로딩 속도가 느릴 수 있지만, 한 번 로딩이 된 후 페이지 간 전환 시에는 빠른 속도로 상호작용을 할 수 있습니다. 만약 다른 페이지에서 필요한 데이터가 있다면 AJAX 요청을 통해 필요한 데이터만 로드하기 때문에 빠른 화면전환을 보여줍니다.

CSR의 단점

SEO에 불리함

CSR의 단점으로 항상 지적되는 것은 바로 검색 엔진 최적화(SEO)에 불리하다거나 초기에 빈 HGTML을 로드하므로 검색 엔진에 노출되지 않는 다는 것입니다. 구글의 경우 검색결과에 CSR 웹 페이지가 노출되기 위해서는 구글 검색에 사용되는 소프트웨어인 Google Bot이 JavaScript 코드를 직접 파싱하고 렌더링을 진행해야 하는데 Google이 지원하는 API 및 JavaScript 기능은 일부 제한되어 있기 때문에 최신 JavaScript를 사용한다면 JavaScript가 정상적으로 작동하지 않아 SEO를 조금 더 어렵게 만들 수 있습니다. 그러나 대부분의 경우는 GoogleBot(크롤러)이 JavaScript를 지원하기 때문에 대부분의 경우 CSR 사이트도 SEO가 잘 이루어집니다.

 

결국 SSR와 비교했을 때, 몇 가지 불리한 점이 있는 것은 사실입니다. 앞서 언급한 일부 JavaScript가 실행되지 않는 문제와 더불어 페이지의 내용을 분석하는 데 더 많은 시간이 걸리기 때문입니다. 다만 구글이 검색을 위해 사용하는 GoogleBot은 페이지 렌더링과 기능 구현에 필요한 JavaScript를 거의 모두 실행할 수 있기 때문에 "치명적인" 단점이라고 할 수는 없습니다. 조금만 더 신경 쓴다면 SSR 못지 않은 SEO를 할 수 있습니다.

느린 초기 로딩 속도

CSR의 초기 로딩 속도는 CSR의 또 다른 단점입니다. 우리 나라의 경우 인터넷 속도가 상당히 빨라 일반적으로는 경험할 수 없지만 인터넷이 느린 환경에서 큰 크기의 JavaScript 번들을 모두 다운로드 받고 실행할 때까지 많은 시간이 걸릴 수 있습니다.

 

결국 Core Web Vitals 측정항목 중 하나인 INP(Interaction to Next Paint, 다음 페인트와의 상호작용)가 증가하게 됩니다. INP의 증가는 구글의 검색 엔진에 노출될 확률이 줄여 SEO에 부정적인 영향을 미치죠. 다행히 이 문제를 해결하기 위한 방법은 있습니다. 사용자에게 필요한 항목만 제공하기 위해 JavaScript를 지연 로드하여 초기 로드에 필요한 JavaScript 파일의 크기를 줄이는 것이죠.

INP(Interaction to Next Paint)
웹 페이지에서 사용자 상호 작용이 지연되는 정도를 나타내는 지표입니다. 사용자와 상호 작용 한 결과로 웹 페이지의 다음 화면이 그려질 때까지 대기한 시간이라고 생각하셔도 됩니다. INP가 낮으면 페이지가 대다수의 사용자 상호작용에 일관되게 빠르게 반응할 수 있다는 의미입니다.

 

저도 이전에 SSAFY(삼성 소프트웨어 부트캠프)에서 프로젝트를 진행하였을 때, 리액트를 이용한 웹 애플리케이션의 크기가 상당히 커진 적이 있었습니다. 저의 경우 코드 스플리팅과 압축을 통해 해결하였지만 코드 스플리팅을 추가하는 것은 CSR의 장점인 빠른 페이지 전환을 어느정도 포기해야하는 방법이기도 합니다.

Server Side Rendering(SSR)

SSR은 "스케치"가 완성된 그림을 보내주는 것과 같습니다. 출처: Copilot

SSR은 웹 애플리케이션의 초기 로드 시에 서버에서 HTML을 생성하고 브라우저에 전달하는 방식입니다. 웹 어플리케이션이 작동하기 위한 JavaScript 파일을 보내는 대신 JavaScipt를 서버에서 실행하여 HTML 파일을 만든 뒤 클라이언트 측에 보내주죠. 브라우저가 JavaScript를 더 적게 실행하기에 더 빠른 초기 로딩속도를 보여줍니다.

 

SSR의 가장 큰 장점은 검색 엔진 최적화가 용이하다는 것입니다. 완전한 HTML이 서버에서 제공되므로 검색 엔진은 콘텐츠를 쉽게 읽을 수 있습니다. 만약 검색 엔진에 노출되는 것이 필요한 웹 사이트라면 CSR보다는 SSR이 더 유리할 것입니다.

 

SSR은 보안 측면에서도 장점이 있습니다. 서버에서 JavaScript를 실행해 HTML을 렌더링하기 때문에 CSRF 공격에 취약한 클라이언트 측 JavaScript 코드를 줄일 수 있습니다. 물론 SSR을 사용한다고 XSS나 CSRF 공격을 완전히 막을 수 있는 것은 아닙니다.

SSR의 단점

서버의 부하 증가

SSR은 서버의 부하를 증가시킵니다. 단순히 JavaScript 및 초기 HTML과 CSS 파일을 전송하기만 하면 서버에서의 할일이 끝나는 CSR방식과는 다르게 SSR은 JavaScript의 코드를 실행하여 HTML의 DOM tree를 완성하여야 하기 때문에 서버가 할 일이 많아집니다. 이는 SSR을 사용함으로써 피할 수 없는 단점입니다. 위의 장점들을 얻기 위해 포기해야할 부분인 것이죠.

동적인 컨텐츠 표시의 어려움

서버에서 HTML이 완성되기 때문에 동적인 컨텐츠를 표시하기 어렵습니다. 만약 사용자의 상호작용에 따라 다른 컨텐츠를 표시하여야 한다면 CSR 방식을 사용하는 것이 더 나을 수 있습니다. 혹은 SSR을 사용하되 클라이언트 측에서 실행되는 JavaScrtipt 파일을 추가할 수 있습니다. 서버에서 전송된 정적 HTML에 JavaScript를 연결하여 동적인 웹 페이지를 만드는 방법으로 SSR에 CSR의 장점을 추가한 것입니다. 기본적인 틀은 SSR방식이지만 몇몇 JavaScript 코드를 클라이언트에 전송하여 CSR의 장점을 가져올 수 있는 것이죠. 이는 빌드 시점에 HTML을 완성하는 SSG(Static-Site Generation, 정적 사이트 생성)와 SSR의 차이이기도 합니다.

SSR에 대한 오해와 React의 Server Component

SSR은 항상 완성된 HTML을 보내주지는 않습니다. 그림의 퍼즐처럼 빈 부분을 채우기 위해 데이터를 요청하는 JS 코드가 클라이언트에서 실행될 수 있습니다. 출처: Copilot

SSR이 HTML을 미리 그려준다고 해서 완성된 웹 페이지를 그려주는 것은 아닙니다. 대부분의 웹 페이지는 동적인 콘텐츠를 가지기 때문에 SSR을 사용하여도 Hydration이라는 과정을 통해 클라이언트가 백엔드 서버에 데이터를 요청하는 JavaScript 코드를 실행할 수 있도록 합니다. 결국 페이지의 완성은 백엔드 서버에서 데이터 받아온 뒤가 됩니다. 이렇게 되면 CSR과의 차이점은 초기 HTML에 내용이 있는지 없는지의 차이가 되는 것이죠.

 

페이지에 동적인 데이터까지 넣은 방식은 React의 Server Component 등을 이용하여 구현할 수 있습니다. "서버 전용"의 코드를 만드는 것이죠. 이렇게 하면 데이터까지 받아온 뒤 완성된 HTML을 클라이언트에 전송할 수 있습니다. 게다가 Server Component 사용하면 JavaScript 코드는 서버에서 실행되고 클라이언트에 노출되지 않아 악의적인 사용자가 코드를 엿볼 가능성도 줄일 수 있습니다. 코드가 노출됨으로써 발생할 수 있는 정보 노출과 관련된 보안 문제를 감소시킬 수도 있습니다. 다만 서버의 업무는 더 많아지겠죠.

참고 자료

Chrome DevRel, WebDev [Rendering on the Web, Interaction to Next Paint (INP)]
Google 검색센터 자바스크립트 검색엔진 최적화의 기본사항 이해하기

+ Recent posts