서버 사이드 렌더링과 클라이언트 사이드 렌더링

Nuxt.js & Vue.js 시작하기 전

SSR & CSR

이번 포스팅은 Vue.js & Nuxt.js를 하기 전에 서버사이드 렌더링과 클라이언트 사이트 렌더링에 대해 짧게나마 정리해보는 것이 필요하다고 생각되서 쓰게 되었다.

1. SSR과 CSR의 MVC 패턴

SSR과 CSR은 HTLM 페이지 렌더링 방식으로 아래의 이미지처럼 Rendering을 어디서 하냐에 따라 Server-Side 또는 Client-Side로 구분된다. (그 외에 Rehydration, Prerendering 방식이 있긴한데 여기선 생략 - 참고 - developers.google.com의 웹 렌더링 포스팅)

SSR과 CSR의 MVC 패턴

Server-Side MVC 패턴의 경우, Rendering 및 HTML Serving을 위한 View와 Controller가 Server에서 처리하지만 Client-side MVC 패턴의 경우에는 서버로부터 서비스 진입 초기에 HTML 파일 + JS 파일 및 리소스 파일 등을 모두 다운 받은후 Client에서 직접 Controller와 View를 담당한다.

2. SSR (Server-Side Rendering, 서버 측 렌더링)

Server-Side Rendering

SSR의 위 순서를 이해해보자.

  1. 사용자가 웹사이트를 요청한다.
  2. 서버가 “렌더링 하기 위한(Ready to Render)” HTML 파일(들)을 만든다.
  3. 브라우저가 HTML 파일을 빠르게 렌더링 할 수 있지만, 사이트는 아직 상호작용(interactive)할 수 없다.
  4. 브라우저가 Javascript를 다운로드한다.
  5. 사용자가 컨텐츠를 볼 수 있으며 상호작용(interactions)이 기록된다.
  6. 브라우저가 JS 프레임워크를 실행한다.
  7. 기록된 상호작용(들)이 실행될 수 있고, 페이지가 상호작용(interactive)한다.

3. CSR (Client-Side Rendering, 클라이언트 측 렌더링)

Client-Side Rendering
CSR의 위 순서를 이해해보자.

  1. 사용자가 웹사이트를 요청한다.
  2. CDN이 빠르게 JS가 연결된 링크와 함께 HTML 파일(들)을 제공한다.
  3. 브라우저가 HTML 파일을 다운로드 한 후, JS를 다운로드 한다. 그동안, 사용자는 사이트를 볼 수 없다.
  4. 브라우저는 Javascript를 다운로드 한다.
  5. JS가 실행되고 API가 데이터를 요청하는 동안 사용자는 placeholder를 본다.
  6. 서버가 API에 대한 응답으로 데이터를 제공한다.
  7. API 응답으로 온 데이터는 placeholder를 채우고, 페이지가 상호작용(interactive)한다.

4. SSR과 CSR의 성능

SSR과 CSR의 Rendering 순서에는 확연히 차이가 존재하며 이에 따라 성능에서도 차이가 존재한다. 아래 목록은 브라우저 렌더링에 있어서 어떤 장단점이 있는지 설명하는데 도움이 되며 또한 렌더링 방식에 따른 최적화를 하는데에도 도움이 되는 지표들이다.

  • TTFB (Time to First Byte): (첫 번째 바이트까지의 시간) - 링크를 클릭한 시점부터 처음으로 콘텐츠의 바이트가 들어오는 시간차

  • FP (First Paint): 픽셀이 처음으로 사용자에게 표시되는 시점

  • FCP (First Contentful Paint): 요청 콘텐츠(기사(article) 본문 등)가 표시되는 시점

  • TTI (Time to Interactive): 페이지가 상호작용 가능하게 될 때까지의 시간 (이벤트 발생 등).

1) SSR Performance

SSR 퍼포먼스

기본적으로 서버 사이드 렌더링은 브라우저에서 응답을 받기 전에 처리되므로 클라이언트에서 데이터 요청 및 템플릿 작성을 위한 추가 요청작업이 발생하지 않아 First Paint 및 First Contentful Paint가 빠르게 생성되며 서버에서 페이지 로직 및 렌더링을 실행하면 많은 JS를 클라이언트에 보내지 않아도 되므로 Time to Interactive를 빠르게 수행할 수 있다.

2) CSR Performance

CSR 퍼포먼스

기본적으로 클라이언트 사이드 렌더링은 JS를 사용해 브라우저에서 페이지를 직접 렌더링 하는 방식으로 가장 처음에 언급한 CSR의 MVC 패턴 을 보면 렌더링 구조를 이해할 수 있다. 서버 사이드에 해당 웹사이트에 대한 자원을 요청하면, 프론트엔드에 대한 bundle.js 또는 app.jsindex.html을 다운받고 번들링 파일을 브라우저의 JS Parser에서 분석한 다음, controller에 해당하는 router 의 정보에 따라 html을 동적으로 생성하는 동시에 사용자에게 보여줄 데이터를 동적으로 요청 및 view 처리해줌에 따라 First Paint 및 First Contentful Paint가 SSR 렌더링 방식보다 오래 걸리며 TTI 또한 오래 걸린다는 단점이 있다.

그럼 왜? CSR 렌더링 방식을 쓰지???

바로 웹사이트 초기 진입시의 FCP 및 TTI가 오래 걸릴뿐이지 그 다음부터는 CSR의 구조 특성상 페이지 이동에 따라 html 파일을 서버에서 reqeust 하는 것이 아닌 클라이언트 단에서 control하며 필요한 데이터면 request하면 되기 때문에 페이지 이동간의 FCP 및 TTI는 SSR보다 좋은 성능을 보인다. 그리고 lazy loading 또는 code splitting을 한다면 페이지별로 필요한 Javascript와 그 외 리소스만 불러올 수 있어서 초기 Rendering 속도를 개선해볼수 있는 가능성도 있다.

5) 정리

정리하자면 각 장단점 또는 차이는 아래와 같으며, 두 렌더링 방식 중 각 어플리케이션의 구조 또는 서비스 페이지의 특징에 따라 적절히 사용하는 것이 중요하다.
대표적으로, 초기 View 로딩 속도, SEO 문제, 보안 문제가 있다.

SSR CSR
초기 View 로딩 속도 CSR에 비해 렌더링 해야하는 파일이 적어 초기 View 로딩 속도가 빠름. 브라우저에서 페이지를 직접 렌더링해야 하므로 초기에는 오래 걸림.
SEO 페이지에 대한 meta 정보가 렌더링시 이미 포함되어 있기 때문에 크롤러봇에서 데이터를 수집해가는데 용이함. 렌더링시 JS 파싱, 로딩 및 실행 순서 때문에 크롤러봇이 데이터를 수집하는데 어려움이 있음.
보안 문제 사용자에 대한 정보를 서버측에서 Session으로 관리 사용자에 대한 정보를 LocalStorage나 Cookie에서 관리해 XSS 공격에 취약함
  • SSR 방식의 경우, 초기 로딩속도가 빠르고, SEO 측면에서 유리하지만
    • View 변경시 서버에 계속 새로운 HTML 파일을 요청해야 하므로 서버에 부담이 큼
  • CSR 방식의 경우, 초기 로딩속도는 느리지만 그 다음 페이지 이동 및 처리에 있어 필요한 데이터만 요청하면 되므로 서버에 부담이 적고, 빠르게 처리할 수 있으나
    • SEO 측면에서 Google 크롤러봇을 제외하곤 Javascript를 실행시키지 못해 데이터 수집하는데 어려움이 있음

참조