지난 포스팅에서, 웹은 클라이언트 (Client)와 서버(Server)로 나누어진다고 했다. 클라이언트(브라우저)가 하는 역할은 서버로 지속적인 요청을 보내는 일이다. 흔히 우리가 주소창에 www.naver.com를 검색을 하는 과정은 ‘www.naver.com에 해당하는 페이지를 내려줘!’라고 클라이언트가 서버에 요청을 보내는 것이고 서버는 요청을 보고 ‘이 요청에 대해서는 이 정보를 응답해줘야지!’하고 알맞은 html을 응답해준다. 그러면 클라이언트는 이 응답받은 html 문서를 보고 문서를 바탕으로 DOM에 html을 그린다. (DOM을 그리면서 CSS + Javascript 코드를 함께 로드한다!)
→ 즉 전통적인 웹은 요청을 보낼 때 마다 페이지에 해당하는 html을 매~번 새로 내려줬다. 그렇게 전체 페이지를 다시 렌더링하는 과정 중에 화면 깜빡임(페이지 리로드)가 발생했고 변경이 필요 없는 부분이 있음에도 페이지를 매번 새로 내려줘야 하니 서버에 부하가 걸렸다.
이 때, AJAX라는 기술이 등장한다. AJAX란 사용자가 요청을 보내면 그 요청에 해당하는 응답의 일부분만 업데이트 할 수 있는 기술이다. 이 개념을 바탕으로 SPA(Single Page Application)
가 등장하게 됐는데 url을 움직이더라도 html을 다시 내려주지 않는 컨셉이다. (우리가 흔히 아는 Angular, Vue, React가 바로 이 SPA를 지원하는 라이브러리들이다)
그리고 이 SPA는 Client Side Rendering 방식으로 동작하는데, 전통적인 웹 동작 방식(브라우저가 서버에서 받은 html을 DOM에 그리는 것)과 다르게, CSR(Client Side Rendering)은 서버에서 HTML을 내려 받는 것이 아니라, 클라이언트(브라우저)가 알아서 화면에 그리는 개념이다.
백문이 불여일견이다. 직접 리액트로 구현한 프로젝트를 브라우저 개발자도구를 통해 살펴보자.
이 일정 관리 어플리케이션은 순수 리액트로만 구현되어 있다. 이 프로젝트를 브라우저에서 열고, 개발자도구를 열어 네트워크 요청을 확인해보자. 네트워크에 Doc(문서)를 클릭해보면, 서버에서 내려준 html을 확인할 수 있다.
이 요청에 대한 응답(Response) 탭을 보면, 엥?
그러면 브라우저가 직접 화면에 그린다는건 뭘까? 이번엔 개발자도구에서 Element 탭을 살펴보자.
아까 분명 네트워크 요청에서는 텅텅 비어있었는데, Element 탭을 보니 div id root 안에 여러 html 요소들이 들어있다. 요건 어디서 나온걸까 하면, 바로 위의 script 태그로 불러오고 있는 bundle.js 파일을 통해 만들어진 것이다. 리액트 프로젝트에서 빌드를 하면, 모든 리액트 코드를 하나의 자바스크립트 파일로 만들어준다.
즉 Client Side Rendering 방식의 웹 페이지는 서버에서 비어있는 html을 응답하고 (<div id=”root”></div>
안이 텅텅 비어있는 것), 클라이언트(브라우저)에서 bundle.js
파일을 읽고 DOM을 그리는 것이다. 그래서 우리가 CSR로 구현된 웹 페이지에서는 페이지 이동을 하더라도 서버에서 html을 그때 그때 새로 다시 내려받지 않고, 페이지 이동을 했을 때 bundle.js
에서 해당하는 코드를 찾아서 DOM에 다시 그리는 방식으로 동작한다.
이러한 방식으로 동작하는 CSR은, 페이지 이동을 했을 때 html을 매번 새로 다시 내려받지 않는다! 그래서 페이지 깜빡임이 발생하지 않아 웹사이트를 사용하는 사용자에게 보다 쾌적함을 제공할 수 있다. 다만, 하나의 bundle.js파일에 모든 프로젝트의 코드가 들어있기 때문에, 프로젝트의 규모가 크면 클수록 bundle.js의 파일의 사이즈도 커질 수 밖에 없다. 그렇기 때문에 최초에 브라우저가 bundle.js 파일을 내려받는 시간이 길어지게 되고, 그러면 처음 화면을 보는데 시간이 오래 걸리게 된다🥹
→ 이런 단점을 해결하기 위해서, SSR(Server Side Rendering) 의 개념이 다시금 떠오르게 됐는데 그건 다음 포스팅에서 정리해보자!