CSR, SSR

junh0328·2021년 9월 20일
0
post-thumbnail

두개의 단어는 서로의 대척점 에 있다고 볼 수 있다.

CSR <-> SSR

해당 개념에 대해 헷갈리지 않도록 조금 더 쉽게 작성해보기로 하였다.

웹 브라우저(크롬, 웨일, 파이어폭스, IE, ...)에서 실제로 우리가 볼 수 있는 화면이 있다.

이러한 화면을 어디서 렌더링하는 지에 따라서 ①CSR과 ②SSR로 구분지을 수 있다.

CSR (Client-Side-Rendering)

대표적인 클라이언트 사이드로 React를 예로 들 수 있다.

CSR, 즉 클라이언트 사이드 렌더링은 SPA(Single Pace Application)에서 주로 쓰이는 기법으로 처음에 브라우저가 서버에 요청할 때 데이터가 없는 문서를 반환한다.

📁 src/App.js

function App() {
  return (
    <div className="App">
      <h1>Hello React</h1>
    </div>
  );
}

export default App;

우리는 기본적으로 App.js 컴포넌트 내부에 <h1>Hello React</h1> 과 같이 작성하였지만, 넘겨 받은 index.html에는 id가 root인 빈 태그를 리턴받았다.

이는 CRA(Create-React-App)을 통해 초기화된 리액트 디렉토리의 구조때문이다.

우리는 리액트를 통해 빌드된 어플리케이션 구조의 최상위에 index.js로 하여금 index.html에 보내주고 있다.

📁 src/index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

reportWebVitals();

이를 public/index.html에 DOM API로 하여금 삽입하는 과정을 거친다.

📁 public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    ...
    <title>React App</title>
  </head>
  <body>
    <!-- 바로 이곳에 id가 root인 div 태그 내부에 우리가 만든 index.js가 들어가게 된다. 🔥-->
    <div id="root"></div>
  </body>
</html>

HTML 및 정적인(static) 파일들이 로드 되면서 데이터가 존재한다면, 데이터 또한 서버에 요청하고, 응답이 완료된 데이터들이 화면 상에 나타나게 된다.

웹 브라우저가 서버에 HTML과 정적 파일들 (.css/.js/.svg/.png/ ...)을 요청한 후 로드되면 사용자의 상호작용에 따라 자바스크립트 엔진에 의해 동적으로 렌더링된다. 필요에 따라 데이터를 서버에 요청하고 받아와 이를 렌더링한다.

실제 작성한 h1 태그로 감싸진 데이터는 main.chunk.js에 들어있다.

CSR을 사용할 경우 첫 HTTP 요청이후 HTML과 그외의 정적인 파일들을 다 받을 경우, 바로 브라우저에 렌더링된다.

TTV == TTI 🔥

따라서 TTV(Time to view 보여지는 시간)와 TTI(Time to interaction 상호작용 가능한 시간)이 일치한다.

렌더링이 완료된 상태에서는 모든 이벤트를 통해 정상적인 사용이 가능하다는 이야기이다.

SSR (Server-Side-Rendering)

SSR의 경우 완전히 만들어진 HTML 파일을 받아와 렌더링한다.

MVC 패턴 중 View 위주로 만들어진 React/Angular/Vue 를 제외한 일반적인 index.html을 렌더링하는 방법은 SSR이라고 봐도 무방하다.

📁 index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <h1>
    Hello HTML!
  </h1>
  <button type="button" class="btn">index2로 가기</button>
  <script>
    document.querySelector('.btn').addEventListener('click', () => {
      location.href=`http://127.0.0.1:5500/csr/index2.html`
    })
  </script>
</body>
</html>
📁 index2.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <h1>
    Hello Index2!
  </h1>
  <button type="button" class="btn">되돌아가기</button>
  <script>
    document.querySelector('.btn').addEventListener('click', () => { history.go(-1)})
  </script>
</body>
</html>

서버에 리소스(index.html, index2.html)를 요청할 때마다 브라우저에 새로고침이 일어나고 매 상황마다 서버에 새로운 페이지를 렌더링해주는 방식이다.

해당 리소스의 응답에는 모두 html 파일이 들어있는 상태이다.

TTV != TTI 🔥

하지만 기본적으로 html 을 먼저 반환해주기 때문에 비동기를 통한 Ajax 요청의 기간이 길어지거나, 요청하는 데이터의 양이 많을 경우 TTV(Time to View)와 TTI(Time to Interaction)이 일치하지 않을 수 있다.

렌더링은 되어 이미 보이지만, 렌더링된 해당 요소들에 대해서 이벤트가 전부 실행되지 않을 수 있다는 뜻이다!

profile
차곡차곡 지식을 쌓아가는 저장소를 만들고 싶습니다

0개의 댓글