본문 바로가기
✍ 따뜻한 개발 공부

그래서 어떤 상황에 뭘 써야 하는데?! / CSR & SSR & ISR 정확히 정리하기

by 따따시 2023. 2. 5.

최종 프젝에 NEXT 적용에 앞서 확실히 이해하고 있나 정리해본 내용들

 

1. CSR  

클라이언트가 요청하면 서버가 js와 html을 보내주고

클라이언트쪽에서 js를 다운받고, js가 돌아가면서 랜더링을 함

(js가 화면을 다 그리기까지 클라이언트 쪽에서 아무 화면을 볼 수 없음

 

2. SSR 

 

클라이언트가 요청을 하면 서버측에서 즉시 "랜더링이 가능한 상태"의 html 파일을 만든다.

그럼 클라이언트는 "랜더링이 즉시 가능한 상태"의 html을 받아서

클라이언트 측에서 js가 실행되고 , HTML이 랜더링이 된다.

(이때 js가 돌아가고 있고 클라이언트는 화면에 보이긴 하지만 실제 돔조작은 안되는 상태)

 

=> CSR과 SSR의 차이 : CSR은 처음에 애초에 하얀 화면이지만 보이는 순간부터 다 만질 수 있고, SSR은 눈에는 먼저 보이지만 클릭해보면 js가 다 실행되기 전까지는 작동은 안되는 껍데기만 보고 있는 상태

 

정리해보면...

 

1) 리액트 : CSR(Client-Side-Rendering)

2) NEXT : SSR(Sever-Side-Rendering), SSG(Static-Site-Generation)

 


NEXT가 SSR, SSG 하는건 알겠는데 구체적으로 어떻게 돌아가는건지 궁금해서 찾아본 내용

 

>> SSR을 언제 쓰고, SSG는 언제쓸지 구글링하다가 너무 정리 잘해놓으신 블로그 발견했고, 해당 블로그 내용들로 공부하면서 다시 정리한 것

헷갈릴때마다 이거 봐야징

https://velog.io/@longroadhome/FE-SSRServer-Side-Rendering-%EA%B7%B8%EB%A6%AC%EA%B3%A0-SSGStatic-Site-Generation-feat.-NEXT%EB%A5%BC-%EC%A4%91%EC%8B%AC%EC%9C%BC%EB%A1%9C

 

[FE] SSR(Server-Side-Rendering) 그리고 SSG(Static-Site-Generation) (feat. NEXT를 중심으로)

앞전 포스트에서 CSR(Client-Side-Rendering)과 SSR(Server-Side-Rendering)에 대한 개념을 살펴보았다. 자세한 내용은 여기를 참고하자.이번 포스팅에서는 SPA 형태의 웹 서비스에서 SSR 방식을 적용하기 위해 Ne

velog.io

 


Next.js는 서버단에서 기본적으로 프리랜더링(사전랜더링)을 해주는 거임

** 프리랜더링이란?? 서버에서 돔 요소들을 빌드해서 HTML 문서를 렌더링하는 것

 

 

 

위 사진처럼 서버측에서 HTML을 프리랜더링을 하고,

그 뒤에 요청이 오면(ex.Link 요청) Chunk 단위로 javascript를 보내주어 이벤트가 작동하게 되는 것

=> 이걸  Hydration이라고 하며, Next.js에서 사용되는 방법이다.

 

Hydrate란,

Server Side단에서 1)랜더링시킨 정적 페이지와 2)번들링시킨 js파일을 클라이언트에게 보낸 뒤

클라이언트측에서 HTML 코드와 React인 js 코드를 서로 매칭시키는 과정

** 번들링이란 ? 여러 개의 흩어져있는 파일을 압축, 난독화 등을 통해 하나의 파일로 모아주는 거

 

  • React.js : Html과 JS파일을 한꺼번에 보내고 클라이언트가 js 코드를 통해 웹 화면을 렌더링
  • Next.js : 서버 쪽에서 프리랜더링 시킨 HTML 클라이언트에게 먼저 보내주고, React가 번들링된 js를 클라이언트에게 전송한다.

NEXT로 프로젝트를 만들고 실행하면 맨 처음 다큐먼트 타입의 파일을 전송받고, 그 이후에 랜더링된 리액트.js 파일들이 Chunk 단위로 다운로드 되는 것을 확인할 수 있다.

 

이전에 보내진 HTML DOM 요소 위에 리액트 코드들이 한번 더 랜더링을 하게 되는데  이 과정이 Hydrate이고

이미 먼저 받아졌던 다큐먼트 타입의 DOM 요소에 나중에 들어오는 js가 매칭이 되는 것이므로

웹 페이지를 다시 그리는 과정이 일어나지 않는다고 한다. 

 

이러한 빌드 과정이 SSR인 것이 아늼!!!!!!!!!!!!! 

(SSR이랑 SSG 둘 다 프리랜더링은 이미 있음, 단지 이게 '동적'이냐 '정적'이냐의 차이인 것)

서버에서 pre-rendering하는 것까지가 Next.js의 특징인 것이고

 

⭐️ pre-rendering을 동적으로 해서 페이지를 생성하느냐(SSR)

 정적으로 페이지를 생성하느냐(SSG)의 차이가 SSR과 SSG의 차이 ⭐️

 

 

1) SSG는 ?

SSG "빌드할 때" pages 폴더에서 작성한 각 페이지들에 대해 각각의 문서를 생성해서 static한 파일로 생성한다.

 

만약 해당 페이지에 대한 요청이 추후에 들어오면

이 페이지들을 그 시점에 생성하는 것이 아니라 이미 빌드할 때 만들어놨던 페이지를 반환하는 형태로 동작하는 것

따라서 React의 CSR보다 응답속도가 빠르다는 장점이 있고 Next.js에서도 SSG 사용을 지향한다 한다.

(CSR는 필요할 때, 요청을 보내고 클라이언트 측에서 파바바박 만들어지는거)

따라서 요청에 대해 동일한 정보로 반환하는 경우에는 SSG를 사용하는 것

 

 

getStaticProps

Next.js에서 SSG를 사용하려면 getStaticProps를 사용하면 되는데,

getStaticProps는 서버 측에서만 실행되는 함수로 getStaticProps는 클라이언트 측에서 실행되지 않는다.

빌드 시에 딱 한 번만 호출되며, static file로 빌드 되는데, 이 함수는 API와 같은 외부 데이터(SQL, ...)를 받아 Static Generation 하기 위한 용도이다.

 


export const getStaticProps = async () => {
  const res = await axios.get(`https://jsonplaceholder.typicode.com/posts`);
  const data = res.data;

  return {
    props: {
      listData: data,
    },
  };
};

const HomePage = ({ listData }:any) => {

  return (
    <div>
      {listData.length &&
        listData.slice(0, 5).map(
          (item:any) => <li key={item.id}>{item.title}</li>)}
    </div>
  );
};

export default HomePage;

HomaPage 페이지가 호출되면 getStaticProps()가 먼저 실행되고 서버에서 받은 데이터를 props에 담아 리턴해준다.

위와 같이 getStaticProps()를 사용해서 코드를 작성한 후 build를 하면, 사전에 서버에서 API를 호출을 해서 데이터를 담고, 그 데이터가 담긴 HTML을 생성한다.
 

getStaticPaths

getStaticPaths는 동적 라우팅으로 어떤 페이지는 동적으로 생성하고, 어떤 페이지는 정적으로 생성하고 싶을 때 사용한다.

import React from "react";
import axios from "axios";

// 마지막으로 testFuc가 실행된다.
const testFuc = ({ item }:any) => {
  return (
    <div>
      {item && (
        <div>
          <h1>{item.title}</h1>
          <p>{item.body}</p>
          <p>{item.id}</p>
        </div>
      )}
    </div>
  );
};

export default testFuc;

// 먼저 getStaticPaths가 실행이 되고 ,return으로 static하게 쓰고 싶은 id 값들을 넘겨줬다.
export const getStaticPaths = async () => {
  return {
    paths: [
      { params: { id: "1" } },
      { params: { id: "2" } },
      { params: { id: "3" } },
    ],
    fallback: true,
  };
};

// 두번째로 getStaticProps가 실행되는데, ctx를 넘겨받았다(getStaticPaths에서 리턴해준거)
export const getStaticProps = async (ctx:any) => {
  const id = ctx.params.id;
  const res = await axios.get(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  );
  const data = res.data;

  return {
    props: {
      item: data,
    },
  };
};

getStaticPaths에서 id가 1,2,3인 페이지는 정적으로 지정했줬기 때문에 1~3 페이지는 static 페이지로 빌드 시점에생성된다.

( npm run build시 1~3 페이지가 생성된다.) 

 

예를 들어, 1번 페이지를 요청보내면 미리 만들어진 static페이지가 오지만 10번 같은, 지정해놓지 않은 페이지를 요청하면

페이지가 먼저 로딩되고 이후에 내용이 채워지는 것을 볼 수 있다고 한다. 

 

  1. Static-Generation  : HTML을 빌드 타임에 각 페이지별로 생성하고 해당 페이지로 요청이 올 경우 이미 생성된 HTML 문서를 반환한다.
  2. Server-Side-Rendering : 요청이 올 때 마다 서버측에서 요청받은 HTML 문서를 그때 그때 생성해서 보내줌

두 방식은 Next에서 pre-rendering을 어떻게 그리고 언제 제공하는지에 대한 차이이다.

SSG는 클라이언트 쪽에서 요청이 들어오면,

요청이 올때마다 서버에서 생성하는 것이 아니라 이미 빌드 시점에 만들어놨던, 생성이 이미 완료된 페이지를 반환해주게는 것

따라서 HTML 문서를 재활용 하기에 응답 속도가 매우 빠르다.

 

 

 

댓글