렌더링이란 HTML, CSS JS 파일을 수신하고 파싱하여 결과물을 화면에 그려내는 과정을 말한다. 자세한 단계는 브라우저 동작 원리 글에서 다룬 적이 있는데, 바로 이 렌더링이 발생하는 주체(시점)에 따라 SSR과 CSR이 구분된다.
SSR (Server-side Rendering)
사용자가 서버에 페이지를 요청하면, 서버 측에서 HTML문서 내의 내용들을 렌더링 준비를 끝마친 상태(Ready to Render)로 클라이언트에 전달하는 방식을 말한다. 클라이언트에 전달되는 순간 HTML은 즉시 렌더링되며, 자바스크립트가 읽히기 전이기 때문에 사이트 자체는 조작할 수 없는 상태가 된다. (just-viewable) 이후에 클라이언트가 자바스크립트 파일을 수신하고, 리액트 등의 프레임워크를 통해 컴파일을 끝마친 후에야 페이지를 조작할 수 있게 된다.
요청이 발생할 때마다 해당 과정을 반복하기 때문에 원하지 않는 부분도 다시 렌더링된다는 특징이 있다. 이는 불필요한 자원 소모를 야기시키고, 서버 부하 등의 문제를 불러올 수 있다. 그러나 빠른 HTML 렌더링 덕분에 페이지 최초 로딩 간 좋은 성능을 보인다.
CSR (Client-side Rendering)
클라이언트 측에서 렌더링이 일어나는 방식으로, React와 Vue에서 사용되는 기법이다. 유저가 서버에 페이지 요청을 보내면 HTML 파일과 스크립트 파일을 수신하게 되고, 이를 실행 및 API 호출한 후 데이터를 렌더링하게 된다.
일반적으로 SPA를 지원하는 프레임워크들은 CSR 방식을 통해 렌더링을 처리한다. Single Page Application을 지원하는 리액트와 뷰는 JS파일을 통해 동적으로 HTML 문서가 완성시키기 때문에, CSR을 통해 파일들을 다운로드, 컴파일한 후에야 화면에 출력할 수 있게 되는 것이다.
최초 로딩 속도는 SSR에 비해 느리다는 특징이 있다. 이는 Code splitting으로 어느 정도 해결할 수 있다고 한다. 처음 파일들을 로딩한 이후에는 클라이언트에서 필요한 데이터만 동적으로 가져와 렌더링하기 때문에 최적의 사용자 경험을 제공할 수 있다.
Code splitting
웹 애플리케이션에 사용되는 스크립트 코드를 작은 청크로 나누는 기술이다. 이를 통해 최초 로딩 속도를 향상시키고, 필요한 부분만 다운로드하여 자원 소모를 최소화할 수 있다. 동적 import()나, Webpack 등의 번들러 설정으로 구현할 수 있다.
SEO
검색엔진 최적화를 위해 SSR을 지원하는 NextJS를 필수적으로 익혀야 한다고들 한다. 웹 페이지 정보들을 수집하는 크롤러에 대응하기 위함인데, CSR은 초기 데이터를 받아오는 과정에서 파싱된 데이터가 없기 때문에 크롤러가 이를 빈 페이지로 착각하는 문제가 발생한다고 한다. SSR은 애초에 스크립트 파일이 서버 사이드에서 컴파일되어 넘어오기 때문에 크롤러에 대응하기에 용이하다.
마치며
두 개념의 단점을 보완하기 위해 등장한 것이 NextJS이다. 최초 렌더링 시 SSR을 통해 검색엔진 최적화 문제를 해결하고, 이후엔 CSR 방식을 통해 필요한 부분만 렌더링하여 부하를 줄이는 방식으로 최적화가 이루어진다.
네트워크가 상대적으로 느리거나 검색엔진 최적화가 필요할 때, 페이지 최초 로딩이 빨라야 하는 경우 SSR을,
네트워크가 상대적으로 빠르거나, 데이터가 많아 로딩 화면을 띄울 필요가 있을 때, 페이지 내의 상호작용 요소가 많을 때는 CSR를 적절히 사용하면 좋을 듯 하다.
Reference