맨 땅에 프론트엔드 개발자 되기

NextJS를 사용하는 이유 / SSR, SSG, ISR 본문

코딩 공부 일지/Next JS

NextJS를 사용하는 이유 / SSR, SSG, ISR

헬로코딩 2023. 8. 30. 15:09
728x90

선수지식

CSR 방식에 대한 이해도가 있어야 한다.

 

리액트를 사용하는 이유 (SPA, CSR, SSR)

리액트를 사용하는 이유 (SPA, CSR, SSR) 많은 개발자들에게 사랑받고 있는 리액트!! 현재, 많은 현업 개발자들에 의해 쓰이고 있고, 프론트엔드 개발에 관심이 있다면 다들 한번씩은 들어봤을 것 같

babycoder05.tistory.com

NextJS

NextJS는 ReactJS를 기반으로 한 웹 프레임워크다. ReactJS에서 제공하는 기능 외에 추가적으로 SSR(서버사이드렌더링) 및 이미지 최적화 등의 기능을 더한 것이다. ReactJS만 사용해서도 자체적으로 서버를 구성해 SSR 방식을 구현할 수도 있다. 그렇지만 NextJS가 제공하는 기능들이 최적화가 잘 되어 있기 때문에 가장 널리 사용되고 있다.

SSR과 CSR의 동작 방식의 차이로 설정해주어야 하는 것들이 다르기 때문에 그 차이점에 대해 명확히 알고 있어야 NextJS 어플리케이션의 동작을 구성할 수 있다.

SSR

SSR과 CSR을 구분하는 가장 큰 차이점은 웹페이지를 완성해서 클라이언트에 보내주는지 아닌지와 관련되어 있다. SSR의 경우 서버에서 완성된 페이지를 렌더링하고 나서 페이지를 클라이언트(브라우저)에 보내주고, CSR의 경우 웹페이지를 구축할 수 있는 index.html 파일과 JavaScript 파일만 보내준 뒤 브라우저에서 페이지를 렌더링한다.

 

CSR
브라우저에서 페이지 요청 -> <div id="root"></div>만 가지고 있는 빈 HTML 파일과 js 파일(bundle.js / 전체 루트에 대한 내용을 모두 포함), 스타일시트 등등 보내줌 -> 브라우저에서 페이지를 렌더링 함 -> 클라이언트에 보임
SSR
브라우저에서 페이지 요청 -> 요청한 루트에 해당하는 페이지를 서버에서 렌더링 함 -> 완성된 html 파일을 먼저 클라이언트에 보내주고 (브라우저는 바로 보여주고) js 파일과 스타일시트 등등 내려받음 -> 다 내려받으면 페이지가 동작할 수 있는 상태가 됨

 

사실, 엄밀히 말하자면 요즘에 쓰는 SSR 방식은 CSR 방식을 혼합해서 사용하기 때문에 Universal Rendering이라고 불러야 한다. 요즘의 거의 모든 웹사이트는 단순히 정보 제공만 하는 단방향 웹사이트 보다는 사용자가 상호작용을 하는 양방향 웹앱이 대부분이기 때문이다. 

그렇다면, CSR만 사용해도 되는데 어떤 경우에 SSR을 사용할까?

 

  • 웹사이트가 거대해서 bundle.js의 로딩속도가 길 때
  • SEO(검색엔진 최적화)가 필요할 때
  • 위키피디아 같이 사용자와 상호작용이 없는 웹페이지일 때 (비용상으로 CSR이 필요하지 않으므로)

 

SEO와 관련한 내용을 설명하자면, 배포작업을 마쳐 웹사이트를 클라이언트에 제공할 준비가 완료되면, 구글, 네이버와 같은 검색엔진들은 상시 웹크롤링 프로그램을 통해 그러한 사이트들의 정보를 추출하고 유저가 검색어를 통해 요청을 했을 때 정보를 제공하기 위해 준비해놓는다. 유저한테 노출이 잘 되게 하기 위해 검색엔진들의 웹크롤링 프로그램이 정보를 잘 추출할 수 있도록 만드는 작업을 검색엔진 최적화(Search Engine Optimization) 라고 한다. 웹크롤링 프로그램들은 웹사이트들의 html 파일로 정보를 추출하기 때문에 (물론, 인가가 필요없는 api의 경우에 한해 데이터 요청 후 정보를 추출하는 웹 크롤러도 있다.) 빈 html만 서버에서 가지고 있는 CSR 방식은 SEO에 취약할 수 밖에 없다.

그래서 SSR 방식으로 미리 상호작용 없는 기본 상태의 html 파일을 서버에서 렌더링 해놓고 웹크롤링에 정보를 제공해줄 수 있도록 하는 방식을 사용하는 것이다.

사용자가 불편함을 느끼지 않도록 CSR과 SSR이 필요한 부분을 각각 파악해 기능을 잘 구현하는 것이 개발자의 능력(?)이라고 할 수 있다.

- getServerSideProps

function Page({ data }) {
  // Render data...
}

// SSR
export async function getServerSideProps(context) {
  // 외부 API로 데이터 가져오기
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

export default Page

NextJS 기본적으로 정적으로 페이지를 생성해두지만, 데이터 페칭이 필요한 경우 getServerSideProps 함수를 이용해서 데이터 페칭 또한 SSR로 구현할 수 있다. (서버에서 데이터를 불러온다는 뜻) 그러나 NextJS는 getServerSideProps를 정말 필요할 때만 사용하라고 권고한다. CDN에 캐싱이 되지 않기 때문에 느리기 때문이다.

SSG

SSG는 Static Site Generation의 약자로 정적 페이지 생성을 말한다. NextJS는 기본적으로 모든 페이지를 서버에서 정적으로 생성해두는데, SSR과 SSG의 차이점은 데이터 페칭을 언제하는 가에 따라 다르다. SSR 방식은 클라이언트가 페이지를 요청하는 시점에 데이터를 요청하고 렌더링 후 클라이언트에 보내주는 반면에, SSG 방식은 빌드 시점에 데이터를 요청해 빌드해놓기 때문에 SSR보다 더 빠르다. 데이터가 계속해서 자주 바뀌는 경우에는 SSR 방식을 사용하는 것이 맞겠지만, 블로그 글 같이 한번 작성된 글이 잘 수정되지 않는 경우에는 SSG 방식을 사용하는 것이 성능과 비용 면에서 낫다. 단, 빌드하는 시점에만 데이터를 요청하기 때문에 실제 데이터베이스에 데이터가 변경되더라도 반영이 되지 않으므로 잘 판단해서 구현해야 한다.

- getStaticProps

export default function SSGPage({ dateTime }: SSGPageProps) {
  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
  };
};

getStaticProps 함수는 NextJS에서 제공하는 기능으로 정적 페이지 생성에서 데이터를 요청할 수 있도록 도와준다. 

ISR

ISR은 Incremental Static Regenration의 약자로 SSG와 마찬가지로 빌드 시점에 페이지를 렌더링 한 후, 설정한 시간 마다 페이지를 새로 렌더링한다. SSG의 단점을 보완한 방식이라고 할 수 있다.

export default function ISR20Page({ dateTime }: ISR20PageProps) {
  return (
    <main>
      <TimeSection dateTime={dateTime} />
    </main>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const res = await axios.get('https://worldtimeapi.org/api/ip');

  return {
    props: { dateTime: res.data.datetime },
    revalidate: 20,
  };
};

기본적으로 getStaticProps 함수를 이용하는 방식은 동일하고 추가적으로 revalidate 의 설정 값으로 제공된 값(seconds)에 따라 페이지가 새로 렌더링된다.

 

728x90