# Client Side Rendering & Server Side Rendering (CSR, SSR)

create-react-app이나 vue-cli로 프로젝트를 생성해보면, helloworld 컴포넌트가 자동으로 생성되고, 프로젝트를 빌드하고 실행하면 helloworld 컴포넌트가 보일 것이다. 그런데 프로젝트의 index.html을 찾아서 열어보자. 아마 이런 태그와 기본적인 태그들외에는 특별한 요소가 안보일것이다.. 그런데 어떻게 helloworld컴포넌트가 그려질까?

프로젝트를 빌드하면 webpack과 같은 정적파일을 합쳐주고 관리하는등 여러가지 일을 자동으로 해주는 모듈번들러가 bundle.js를 생성해준다. 클라이언트가 배포된 프로젝트의 url로 접근하면, bundle.js와 index.html등 정적파일을 클라이언트의 웹브라우저가 전달받는다. 그리고 클라이언트의 웹브라우저의 js엔진이 bundle.js를 열심히 해석하여 화면을 렌더링한다. 이런방식이 CSR이다.

위에서는 설명하기 편하도록 CSR로 SPA를 예로 들었는데, SPA가 CSR 방식이지, 같은 것은 아니다.

next.js같은 경우는 하이브리드다. 부분적으로만 ssr을 적용할수있다. 결국 CSR이라는 것은 서버에서 태그를 내려주는것이 아닌, 자바스크립트로 DOM을 생성하는것이다.

첫페이지에서 js를 로드하고 동적으로 태그를 생성하기때문에 첫페이지로딩이 상대적으로 느리다. 하지만 그후로는 성능이 좋다. js파일내에 모든 페이지 정보가 있기 때문에.. 그래서 코드스플리팅개념이 등장했다. 처음부터 모든 페이지 정보를 불러오는게 아니라, 웹팩 설정을 통해 페이지 정보와 기능을 나눠서 로드할수있다. 그러면 당연히 처음에 로드되는 파일사이즈가 작아지므로 첫 페이지 로드 성능이 좋아진다.

csr에는 또 다른 중요한 단점이 존재한다. 번들링된 js에 모든 프론트정보가 담기므로, 보안에 신경써야한다. 그래서 결제모듈등을 구현할때, 해당 모듈의 시크릿 키는 프론트코드내에 있으면 절대로 안된다. 개인정보나 결제시스템이 있다면 ssr로 구현하는것이 당연히 보안적으로 유리하다.

반대로 SSR은 클라이언트가 url을 요청하면, url에 해당하는 서버에서 태그들을 열심히 생성해서 클라이언트에 생성한 태그를 리턴한다. 그러면 클라이언트에서는 이미 생성된 html만 렌더링하면되므로, 초기 로딩속도가 빠르다. 네트워크를 통해서 가져오는 패킷크기도 작을것이다. js로 DOM을 handling하여 화면을 렌더링하는것보다 브라우저가 태그를 파싱해서 렌더링하는것이 빠르다. 하지만 서버에서 클라이언트들이 볼 페이지를 렌더링하므로 서버과부하를 막기위한 전략이 필요하다 좋은 전략은 역시 캐싱이고, 일부분은 클라이언트에서 렌더링하는방식이 좋다.

제일 좋은 구현 방법은 보통 크롤링이 필요한 페이지와 빠른 로딩이 필요한 첫페이지에 SSR을 적용하고, 나머지 페이지들은 CSR로 구현하는것이 성능적으로는 바람직하다. 첫 페이지 로딩속도는 사용자 접속률에 중요한 영향을 끼치고(3초 이내), CSR을 크롤링 할 수 없는 검색엔진이 대부분이기 때문에(자바스크립트 엔진이 내장된 크롤러가 많지않다)이다. react를 선택했다면, next.js가 가장 무난하고 좋은선택이다. vue에는 nuxt.js가 있다.

그렇다면 어떤때에 SPA, SSR을 결정하는가? 보통 이렇게 결론이 내려진다.

대부분의 어드민페이지 => SPA 일반적인 웹사이트 대부분 => SSR

위에서 설명했던 내용을 이해했다면, 대부분의 프로젝트가 이런식으로 결정된다.