CSR & SSR

1Hoit·2023년 1월 31일
0

React 기초

목록 보기
7/12

SPA 와 MPA

  • SPA (Single Page Application)
  • MPA (Multi Page Application)
    • 페이지의 구성 방식에 따라 SPA, MPA 가 나뉜다.
    • 렌더링 방식에 따라 CSR, SSR 이 나뉜다.

      즉, SPA !==CSR MPA !== SSR 인 셈이다.

위 내용은 SSR과 CSR과 밀접한 관련이 있다.

CSR & SSR

CSR : Client Side Rendering
SSR : Server Side Rendering

참고

SSG: Static Site Generation
SSR SSG 차이는 서버에서 요청 시에 즉시 만드느냐 미리 만들어 놨느냐의 차이다.

SSR: 요청시 즉시 만들기에 데이터가 자주 업데이트 되서 미리 만들기 어려운 페이지에 적합
SSG: 미리 다 만들어 두기에 바뀔 일이 거의 없는 페이지에 적합

SSR, CSR 차이점

SSR과 CSR의 주요 차이점은 페이지가 렌더링되는 위치다.
SSR은 서버에서 페이지를 렌더링하고,
CSR은 브라우저(클라이언트)에서 페이지를 렌더링한다.

CSR 동작 과정과 특징

동작 과정

  1. User가 웹사이트 방문시 브라우저가 서버에 콘텐츠 요청
  2. 서버는 빈 뼈대 HTML(단일 페이지(Single Page))과 연결된 JS링크를 브라우저에 응답으로 넘겨줌
  3. 브라우저가 연결된 JS링크를 통해 서버로부터 다시 JS파일을 다운 받고 JS를 이용해 동적으로 페이지를 만들어 브라우저에 띄운다(렌더링한다).

    (웹 페이지에 필요한 내용이 데이터베이스에 저장된 데이터인 경우
    브라우저는 데이터베이스에 저장된 데이터를 가져와서 웹 페이지에 렌더링을 해야하는데 이때 Fetch와 같은 API가 사용된다.)

  4. 만일 브라우저가 다른 경로로 이동하면 CSR에서는 SSR과 다르게, 서버가 웹 페이지를 다시 보내지 않는다.
    브라우저는 브라우저가 요청한 경로에 따라 페이지를 다시 렌더링한다. 이때 보이는 웹 페이지의 파일은 맨 처음 서버로부터 전달받은 웹 페이지 파일과 동일한 파일이다.

특징

  1. 초기 로딩 속도가 느림
    CSR은 브라우저가 JS파일을 다운로드 받고 동적으로 DOM을 생성하는 시간을 기다려야하므로
  2. 초기 로딩 이후 구동 속도 빠름
    초기 로딩 이후 페이지 일부 변경시 서버에 필요한 데이터만 요청하므로
  3. 서버 부하가 적음
    서버가 빈 뼈대만 있는 HTML을 넘겨주기 때문
  4. 반응 속도가 빠르고 UX(사용자 경험)도 우수
    클라이언트 측에서 연산, 라우팅 등을 처리하므로
  5. SEO 검색엔진 최적화에 불리함
    웹 크롤러 봇 입장에서 본 HTML은 비어있기 때문

참고
브라우저들이 가지는 웹 크롤러는 HTML을 읽어서 검색 가능한 색인을 만들어 낸다.
보통의 크롤러 봇은 JS를 읽지 못하고 HTML을 읽는다
단, 크롬 크롤러 봇은 JS도 읽을 수 있다고 한다.

SSR 동작 과정과 특징

동작 과정

  1. User가 웹사이트 방문시 브라우저가 서버에 콘텐츠 요청
  2. 서버는 즉시 페이지에 필요한 데이터를 얻어와 모두 삽입하고 CSS까지 모두 적용해서 렌더링 준비를 마친 HTML과 JS 코드를 브라우저에 응답으로 전달함.
  3. 브라우저는 전달 받은 페이지를 바로 띄운다.
    그리고 JS코드를 다운로드하고 HTML에 JS 로직을 연결한다.
  4. 브라우저가 다른 경로로 이동할 때마다 서버는 같은 작업을 다시 수행하게 된다.

특징

  1. 검색엔진 최적화에 유리
    서버에서 렌더링 준비를 마친 HTML 브라우저의 응답으로 전달하므로 모든 데이터가 HTML에 담겨진 채로 브라우저에 전달 되기 때문이다.
  2. 사용자가 화면을 빨리 볼 수 있다.
    JS 코드를 다운 받고 실행하기 전에 화면을 볼 수 있다.
    JS 다운로드를 기다려야 했던 CSR 보다 초기 구동 속도가 빠르다.
  3. 사용자 화면을 빨리 볼 수 있지만 사용자가 버튼 클릭이나 이동 등을 해도 아무런 반응이 없을 수 있다.
    HTML에 JS로직이 연결되기 전까지 사용자 입력에 응답 할 수 없다.
    TTV(Time To View) 와 TTI (Time To Interact)의 간격이 존재한다는 이야기다.

CSR과 SSR의 장단점 정리

CSRSSR
장점화면 깜빡임이 없음
초기 로딩 이후 구동속도가 빠름
TTV와 TTI사이 간극이 없음
서버 부하가 분산 된다.
초기구동 속도가 빠름
SEO에 유리함
단점초기 로딩 속도가 느림
SEO에 불리함
화면깜빡임이 있음
TTV와 TTI사이 간극이 있음
서버 부하가 있음

CSR 단점 보완 방법

  1. 초기 로딩 속도 보완 방법
  • code splitting
  • tree-shaking
  • chunk 분리

위 3가지를 통해 JS 번들 크기를 줄여 초기 DOM 생성 속도를 줄이면 된다.

  1. SEO 개선 방법
  • pre-rendering

라이브러리나 웹팩 플러그인을 통해 각 페이지에 대한 HTML 파일을 미리 생성 해둔 뒤 서버에서 요청하는 자가 만약 크롤러라면 사전에 렌더링 된 HTML 버전 페이지를 보여주는 방식을 통해 개선할 수 있다.

  1. SSR, SSG 도입을 통해 CSR의 단점을 보완하기
  1. Next.js : 페이지의 성격별로 SSR, SSG 정할 수 있다.
  2. Gatsby.js : 리액트 기반 정적 페이지 생성 프레임 워크로 SSR에 최적화 되었지만 CSR, SSR, 레이지 로딩 지원

이밖에도 많지만 위 내용은 다음에 다루겠다.

무엇을 써야할까?

서비스의 성격에 따라 다르다.
CSR : 유저와 상호작용이 많고 대부분이 개인 정보로 이루어진 페이지들이라면 검색엔진에 노출되기 보다는 고객의 데이터를 보호하는 것이 더 중요하므로 CSR사용

SSR : 회사 홈페이지와 같이 누구에게나 동일한 내용을 노출하고 있으며 그 페이지의 데이터가 자주 업데이트 될 때 SSR 사용, 만약 내용을 업데이트 하는 일이 거의 없다면 SSG 가 더 적합하다.

만약 모든 것을 포기할 수 없다면 유니버셜 렌더링
즉, SSR + CSR 이 적합

예시 코드

SSR 코드 예시

const express = require("express");
const app = express();

const infoArr = [
  "csr과 차이점이 느껴지나요?",
  "ssr이란?",
  "HTML은 어디서 조작될까요?",
  "Server Side Rendering",
  "검색엔진 최적화(Search Engine, Optimization)에 상대적으로 유리하다.",
  "초기로딩 속도가 빠르다.",
  "TTV(Time To View)와 TTI(Time To Interact)의 시간 공백이 있을 수 있다."
];

app.get("/", (req, res) => {
  res.send(
    "<html><body><h1>" +
      infoArr[Math.floor(Math.random() * infoArr.length)] +
      "</h1><h1>SSR</h1>" +
      "<h2>Server Side Rendering이란 무엇인가?</h2>" +
      "</body></html>"
  );
});

app.listen(8080);

CSR 코드 예시

const express = require("express");
const app = express();
const port = process.env.PORT || 5000;

const infoArr = [
  "ssr과 차이점이 느껴지나요?",
  "csr이란?",
  "SPA를 기반으로",
  "화면의 일부만 바꿔주는 것",
  "HTML은 어디서 조작될까요?",
  "Client Side Rendering",
  "AJAX를 통해서 서버로부터 필요한 데이터만 받습니다."
];
app.get(`/`, (req, res) =>
  res.send(infoArr[Math.floor(Math.random() * infoArr.length)])
);
app.get(`/csr`, (req, res) =>
  res.send(infoArr[Math.floor(Math.random() * infoArr.length)])
);

app.listen(port, () =>
  console.log(`Example app listening at http://localhost:${port}`)
);
profile
프론트엔드 개발자를 꿈꾸는 원호잇!

0개의 댓글