기은P
시간이 멈추는 장소
기은P
  • Programming (272)
    • 개발노트 (1)
    • FrontEnd (56)
      • ES&JS 문법 (14)
      • HTML&CSS (4)
      • React 기본 (18)
      • React 심화 (12)
      • React 이슈 (2)
      • Project 연습 (1)
      • Next.js (5)
    • Backend&Devops (33)
      • AWS (2)
      • Docker (9)
      • Jenkins (6)
      • Nginx (6)
      • Node.js (1)
      • ElasticSearch (5)
      • 프레임워크&아키텍처 (2)
      • 암호화 (0)
      • 기타 (2)
    • 알고리즘 (3)
    • C# (8)
      • WPF (8)
    • Java (51)
      • 순수 Java (18)
      • RDF&Jena (12)
      • RCP&GEF (9)
      • JMX (5)
      • JMapper (3)
      • 오류해결 (4)
    • Database (21)
      • RDBMS (9)
      • NoSQL (2)
      • TSDB (1)
      • GraphQL (1)
      • Hibernate (3)
      • 데이터베이스 이론 (4)
      • Redis (1)
    • 프로토콜 (11)
      • Netty (4)
      • gRPC (5)
      • 프로토콜 개념 (2)
    • Server (4)
      • Linux (4)
    • 2020 정보처리기사 필기 (43)
      • 목차 (1)
      • 기출문제 (1)
      • 1과목 - 소프트웨어 설계 (6)
      • 2과목 - 소프트웨어 개발 (7)
      • 3과목 - 데이터베이스 구축 (8)
      • 4과목 - 프로그래밍 언어 활용 (7)
      • 5과목 - 정보시스템 구축 관리 (10)
    • 2020 정보처리기사 실기 (31)
      • 목차 (4)
      • 기출예상문제 (19)
      • 실기요약 (8)
    • 빅데이터분석기사 필기 (4)
      • 목차 (0)
      • 필기 요약 (3)
    • 전기 공학 (1)
      • CIM (1)
    • 산업자동화시스템 (3)
      • SCADA (1)
      • OPC UA (2)
    • 디자인패턴 (1)
    • 휴지통 (0)

공지사항

  • 공지사항/포스팅 예정 항목

최근 댓글

최근 글

전체 방문자
오늘
어제

티스토리

hELLO · Designed By 정상우.
기은P

시간이 멈추는 장소

[Next.js] SSG, SSR 개념 정리
FrontEnd/Next.js

[Next.js] SSG, SSR 개념 정리

2022. 6. 2. 16:32
반응형

1. 개요

전 글에서는 Hydrate에 대해서 알아봤는데, 이번에는 SSG(Server-Side-Generation, Static-Site-Generation)와 SSR(Sever-Side-Rendering)에 대해 알아보려고 합니다.

 

CSR에 알고 싶으신 분은 아래 링크 참고 부탁드릴게요!

https://narup.tistory.com/264?category=1044606 

 

[React] SSR과 CSR(SPA) 차이

1. 개요 먼저 브라우저가 동작되어 우리에게 정보를 표현할 때, HTML의 정보를 읽어 이를 내부적으로 렌더링 한 후 js나 css를 반영해 최종적으로 정보를 표현합니다. 이러한 렌더링을 하는 방식이

narup.tistory.com

 

React: CSR(Client-Side-Rendering)

Next.js: SSR(Sever-Side-Rendering), SSG(Static-Site-Generation)

 

사실 Next.js에 대해 공부하는 사람들은 React가 어떤 식으로 작동하는지에 대해 기본적으로 알고 있다고 생각하기에, CSR에 대한 개념은 생략하고, Next.js가 어떤 방식으로 작동하는지에 대해 알아보려고 합니다.

Next.js는 브라우저에 렌더링 할때 기본적으로 pre-rendering(사전 렌더링)을 해줍니다.

사전 렌더링이란? Server단에서 DOM 요소들을 Build하여 HTML 문서를 렌더링하는 것을 말합니다.

 

 

위 사진처럼 HTML을 미리 렌더링하고, 그 뒤에 요청이 오면 Chunk 단위로 javascript를 보내주어 이벤트가 작동하게 되는 것이 Hydration이며, Next.js에서 사용되는 방법입니다.

https://narup.tistory.com/230

 

[Next.js] Hydrate란?

1. 개요 Hydrate란, Server Side단에서 렌더링 된 정적 페이지와 번들링된 js파일(Webpack)을 클라이언트에게 보낸 뒤, 클라이언트 단에서 HTML 코드와 React인 js 코드를 서로 매칭시키는 과정을 말합니다.

narup.tistory.com

 

이러한 빌드 과정, 웹 페이지 요청 과정이 SSR인 것은 아닙니다!

서버에서 pre-rendering하는 것까지가 Next.js의 특징인 것이고, pre-rendering을 동적으로 해서 페이지를 생성하느냐, 정적으로 페이지를 생성하느냐의 차이가 SSR과 SSG의 차이라고 생각하시면 됩니다.

 

 

2. SSG(Static-Site-Generation)

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

만약 해당 페이지에 대한 요청이 발생하게 되면, 이 페이지들을 재생성하는 것이 아니라 이미 생성이 된 페이지를 반환하는 형태로 동작합니다. 따라서 React의 CSR보다 응답속도가 빠르다는 장점이 있고 Next.js에서도 SSG형태로 사용하는 것을 지향하고 있습니다.

마케팅 페이지, 블로그 게시물, 제품의 목록과 같이 정적 생성된 정보를 각 요청에 동일한 정보로 반환하는 경우에 위 SSG를 사용합니다.

 

2-1. getStaticProps

Next.js에서 SSG를 사용하려면 getStaticProps를 사용하면 됩니다.

getStaticProps는 서버 측에서만 실행되는 함수로 getStaticProps는 클라이언트 측에서 실행되지 않습니다. 빌드 시에 딱 한 번만 호출 되며, static file로 빌드 되는데, 이 함수는 API와 같은 외부 데이터(SQL, ...)를 받아 Static Generation 하기 위한 용도입니다.

 

About.tsx

import axios from 'axios';
import React from 'react'
import { useEffect } from 'react';
import { useState } from 'react';


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

  console.log(data[1]);

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

const About = ({ list }:any) => {
  // const [list, setList] = useState([]);

  // useEffect(() => {
  //   const getList = async () => {
  //     const res = await axios.get(`https://jsonplaceholder.typicode.com/posts`);
  //     const data = res.data;
  //     setList(data);
  //   };
  //   getList();
  // }, []);

  return (
    <div className="About">
      <h1>About 페이지</h1>
      {list.length &&
        list.slice(0, 10).map(
          (item:any) => <li key={item.id}>{item.title}</li>)}
    </div>
  );
};

export default About;

About 페이지가 호출되면 getStaticProps()가 먼저 실행되며 fetch를 통해(혹은 axios) 게시물 리스트를 가져오고 그 이후에 props에 리턴값을 담아서 About에 전달합니다.

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

 

 

2-2. getStaticPaths

getStaticPaths는 동적 라우팅으로 페이지를 동적으로 생성할 때, 특정 페이지는 정적으로 생성하고 싶을 때 사용합니다.

동적 라우팅: "/pages/boards/[id].js" 과 같이 게시글 같은 것들을 외부에서 가져와서 동적으로 페이지를 생성해서 연결하는 것을 말합니다. 

getStaticPaths는 예를 들어, 웹 페이지에 공지사항과 같은 특정 게시물만 정적으로 생성하고 싶을 때 사용합니다.

 

pages/detail-static/[id].tsx (pages/detail-static/[id].js js쓰시면 :any는 빼주시면 됩니다)

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

const DetailStatic = ({ item }:any) => {
  return (
    <div>
      {item && (
        <div className="Detail">
          <h1 style={{ color: "#fff" }}>with Static Generation</h1>
          <h1>{item.title}</h1>
          <p>{item.body}</p>
          <p>{item.id}번째 게시글</p>
        </div>
      )}
    </div>
  );
};

export default DetailStatic;

export const getStaticPaths = async () => {
  console.log("path")
  return {
    paths: [
      { params: { id: "1" } },
      { params: { id: "2" } },
      { params: { id: "3" } },
    ],
    fallback: true,
  };
};

export const getStaticProps = async (ctx:any) => {
  console.log("props")
  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 -> getStaticProps -> DetailStatic 페이지 입니다.

 

위 getStaticPaths를 보면 리턴값으로 paths에 params로 1,2,3 페이지 번호를 지정했습니다.

그 후에 getStaticProps가 호출되어 ctx.params.id를 읽어 해당 게시글에 대한 데이터를 가져와 페이지를 생성합니다.

getStaticPaths에서 정적으로 지정했기 때문에 이 1,2,3 페이지는 static file로 생성됩니다.

npm run build시 1,2,3 페이지가 생성되어 있다.

http://localhost:3000/detail-static/1

http://localhost:3000/detail-static/5

1번과 5번으로 테스트해보면 1번 페이지는 로딩되지마자 내용이 채워진 페이지가 로딩되고, 5번 페이지는 페이지가 먼저 로딩되며 그 이후에 내용이 채워지는 차이가 있습니다.

 

 

 

3. SSR(Sever-Side-Rendering)

SSR은 유저가 페이지를 요청할 때마다 그에 맞는 HTML 문서를 생성해서 반환합니다.

이러한 특징이 사용되는 경우는 항상 최신 상태를 유지해야하는 웹 페이지나, 분석 차트, 게시판 등, 사용자의 요청마다 동적으로 페이지를 생성해 다른 내용을 보여주어야 하는 경우에 사용됩니다.

 

 

3-1. getServerSideProps

2-1에서 작성한 About 컴포넌트에서 생성된 게시글 리스트의 세부 게시글 정보를 보고 싶을 때는 아래와 같이 코드를 작성해서 사용합니다.

detail이라는 폴더를 만들고 [id].js 파일을 만들어서 아래 코드를 작성합니다.

 

detail/[id].js

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

const Detail = ({ item }) => {
  return (
    <div className="Detail">
      <h1>{item.title}</h1>
      <p>{item.body}</p>
      <p>{item.id}번째 게시글</p>
    </div>
  );
};

export default Detail;

export const getServerSideProps = async (ctx) => {
  const id = ctx.params.id;
  const res = await axios.get(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  );
  const data = res.data;

  console.log(data); // 해당 콘솔은 어디에서 출력이 되나요?

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

 

getServerSideProps에서 인자인 ctx는 context로 

[params] contains the route parameters for pages using dynamic routes. For example, if the page name is [id].js , then params will look like { id: ... }. To learn more, take a look at the Dynamic Routing documentation. You should use this together with getStaticPaths, which we’ll explain later.
[preview] is true if the page is in the preview mode and undefined otherwise. See the Preview Mode documentation.
[previewData] contains the preview data set by setPreviewData. See the Preview Mode documentation.
[locale] contains the active locale (if enabled).
[locales] contains all supported locales (if enabled).
[defaultLocale] contains the configured default locale (if enabled).

위와 같은 정보에 접근이 가능합니다.

 

 

 

참고

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

 

 

반응형
저작자표시 변경금지 (새창열림)

'FrontEnd > Next.js' 카테고리의 다른 글

[Next.js] Antd es module 사용시 이슈(nextjs antd syntaxerror cannot use import statement outside a module)  (0) 2024.06.27
[Next.js] router query(props) 값이 비어있는 오류  (0) 2022.07.15
[Next.js] Proxy Axios 설정  (0) 2022.06.20
[Next.js] Hydrate란?  (0) 2022.05.18
    'FrontEnd/Next.js' 카테고리의 다른 글
    • [Next.js] Antd es module 사용시 이슈(nextjs antd syntaxerror cannot use import statement outside a module)
    • [Next.js] router query(props) 값이 비어있는 오류
    • [Next.js] Proxy Axios 설정
    • [Next.js] Hydrate란?
    기은P
    기은P
    기은P의 블로그 일상과 개발 관련 포스팅 #React #Typescript #Next #Nest https://github.com/kimdongjang

    티스토리툴바