업데이트:

클라이언트 사이드 렌더링, CSR

클라이언트 사이드 렌더링이란 클라이언트 측에서 모든 페이지의 내용을 그리는 것이다.

예제로 알아보자.

서버가 보낸 index.html
<!DOCTYPE html>
<html lang=''>
  <head>
    <!-- ... -->
  </head>
  <body>
    <div id='root'></div>
  </body>
</html>

id가 root인 div 태그 하나만 있다.

app.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <App />
);

자바스크립트가 동적으로 HTML을 생성한다.

문제점


첫 로딩 시간이 오래 걸릴 수 있다.

자바스크립트 파일의 용량이 커질수록 서버에서 받아오는 시간이 오래 걸린다.

SEO(Search Engine Optimization)가 좋지 않다.

검색 엔진들의 경우 웹 사이트의 HTML 문서를 분석해서 검색 결과에 나올 수 있게 등록한다.

하지만 CSR 페이지는 위에서 보았듯이, root 하나만 존재한다.

따라서 검색 엔진들이 웹 페이지를 분석하는데 어려움을 겪게 된다.

서버 사이드 렌더링, SSR

서버 사이드 렌더링은 클라이언트 사이드 렌더링과 반대로 서버에서 페이지를 만들어 클라이언트에 보낸 후, 화면에 표시한다.

이는 위에서 알아보았던 CSR의 문제점 두 가지를 모두 보완할 수 있다.

하지만 문제점도 물론 존재한다.

문제점


깜박임 이슈

사용자가 다른 페이지로 이동할 때, 전체적인 웹사이트를 다시 서버에서 받아 오는 것이기에 깜박이는 것이다.

쉬운 서버 과부하

사용자가 많을 수록 이는 심해진다.

클릭을 할 때마다 서버에 요청 후, 데이터를 받아와 HTML을 만들기 때문에 서버에 과부하가 걸리기 쉽다.

상호작용을 하기까지 시간이 걸린다.

상호작용을 위한 자바스크립트 파일을 아직 받아오지 못했을 경우 클릭을 해도 아무 반응이 없을 수 있다.

페이지가 보인다는 것은 파일을 다 받아온 게 아닌가?

이를 이해하게 위해서 TTV와 TTI를 알고 있어야 한다.

TTV(Time To View)는 사용자가 화면을 볼 수 있는 것이고, TTI(Time To Interact)는 사용자가 클릭 또는 상호작용이 가능한 것을 말한다.

CSR vs. SSR

CSR의 경우 서버에서 index.html 파일을 받아오고, app.js 파일을 받아와 화면을 표시하게 된다.

화면을 표시하는 일과 여러 상호작용 관련된 코드들이 모두 app.js 파일에 포함되어 있기에 사용자가 볼 수 있음과 동시에 상호작용이 가능하다.

즉, CSR은 TTV와 TTI의 공백이 없다.

SSR의 경우 서버에서 잘 만들어진 index.html 파일을 받아오면 사용자가 사이트를 볼 수 있게된다.

이 시점에서는 아직 자바스크립트 파일은 받아오지 않았으므로 상호작용은 불가능하다.

자바스크립트 파일을 받아온 후에야 상호작용이 가능해진다.

즉, SSR은 TTV와 TTI의 공백이 길다.

Cross-Origin Resource Sharing, CORS

CORS는 다른 도메인의 리소스 요청을 안전하게 사용할 수 있게하는 정책이다.

요즘 웹의 경우 프론트 따로 서버 따로 두는 경우가 많다.

이렇게 되면 프론트에서 다른 도메인에 위치한 api 서버로 요청을 넣는 상황이 발생한다.

예전에는 웹 브라우저의 기본 정책상 도메인이 다르면 요청을 주고 받을 수 없었다.

하지만 이제는 CORS를 통해 다른 도메인과 요청을 주고 받는 것이 가능해졌다.

나오게 된 배경


CORS가 나오게 된 배경에 대해 간단히 알아보자.

예전 웹사이트

유저가 웹 브라우저 주소창에 url을 입력한다면,

  1. 해당 서버로 요청을 보냄
  2. 서버는 응답으로 HTML 페이지를 반환

위와같이 예전에는 같은 도메인에서 모든 것이 일어났다.

따라서 다른 도메인으로 요청을 보낼 경우 악의가 있다고 판단해 같은 도메인이 아니라면 요청을 막았었다.

요즘 웹사이트

점점 웹사이트가 복잡해짐에 따라 기존 웹브라우저의 보안 정책에 대해 불편함을 느끼는 일이 많아지게 되었다.

영화 박스오피스 순위를 알려주는 웹 애플리케이션을 예로 들어보자.

웹 브라우저는 영화 순위 정보를 얻기 위해 웹 서버로 요청을 보낼 것이고, 웹 서버는 영화 API 서버에 요청을 보내 정보를 받아올 것이다.

여기서 “굳이 웹 서버를 거칠 필요가 있을까?” 라는 생각이 들 것이다.

웹 브라우저에서 바로 영화 API 서버에 요청을 보내면 더 간단해지지만, 이 경우 도메인이 달라 요청이 막히게 된다.

우회적 방식, JSONP

HTML의 script 태그의 경우 다른 도메인의 정보를 불러오는 것이 가능했다.

script를 불러오는 것처럼 사용을 하지만 실제로는 서버에서 데이터를 반환하는 JSONP라는 방식으로 웹 브라우저에서 다른 도메인에 직접 요청을 보냈다.

공식적 방식, CORS

JSONP의 수요가 막을 수 없이 많아지자 웹 브라우저는 공식적으로 CORS라는 정책을 내놓았다.

CORS 세팅


일반적으로 CORS 세팅을 직접할 일은 없다.

프론트에서 요청을 보낼 때, CORS 옵션을 넣어줄 경우 request 헤더까지 알아서 넣어주기 때문이다.

서버도 마찬가지로 간단한 옵션으로 CORS를 설정해줄 수 있다.

그래도 알아두면 언젠가 도움이 될 것이기에 간단하게만 알아보자.

서로 다른 도메인에 요청을 주고받기 위해서는 프론트와 서버에서 아래와 같은 특정한 작업을 해주어야 한다.

  • 프론트 : request 헤더에 CORS 관련 옵션 추가
  • 서버: response 헤더에 해당 프론트의 요청을 허용한다는 내용 추가

HTTP OPTIONS method


사실 다른 도메인에 요청을 보내는 작업은 요청을 아래와 같이 총 두 번 보내게 된다.

  1. 이 요청을 허용해줄 것인가? — HTTP OPTIONS method
  2. (서버에서 허용한 경우) GET이나 POST로 실제 요청

서버에서도 웹 브라우저로부터 요청을 받으려면 동일한 라우터에 대해 HTTP OPTIONS method 처리를 하도록 작업을 해주어야 한다.

보통은 이 작업을 라이브러리에서 알아서 해준다고 한다.

하지만 이를 잘 활용한다면 특정 라우트만 CORS 요청을 허용하거나 특정 도메인의 요청만 허용하는 것이 가능할 것이다.

Notice: 이 게시물은 Taehoon, 드림코딩 유튜브를 참고하였습니다.

댓글남기기