[NextJS] 정적 생성과 서버사이드 렌더링

15969 단어 nextjsnextjs

사전 렌더링(Pre-rendering)

  • NextJS : 기본적으로 모든 페이지를 Pre-rendering
    *사전에 HTML 파일들을 만든다는 것을 의미
  • 퍼포먼스 향상과 SEO에 유리

1. Pre-rendering vs No Pre-rendering

1) Pre-rendering

  • 사전에 만들어진 HTML 요소들이 화면에 표시(메타데이터 포함)
  • JS가 로드되고 난 후 링크 태그 등이 작동 시작

2) No Pre-rendering

  • 완전 빈페이지에서 시작
  • JS가 로드되고 난 후 채워짐

2. 방식

  • 정적 생성(Static Generation)과 서버사이드 렌더링(Server-side Rendering)의 2가지 방식이 있음
    *페이지별로 정해서 쓸 수 있음
  • 차이 : 언제 HTML을 만드는 가

1) 정적 생성

  • 빌드 시에 HTML을 생성 후 유저들이 요청할 때마다 미리 생성한 HTML 페이지를 재사용해 보여줌

2) 서버사이드 렌더링

  • 요청을 하면 HTML을 생성 후 보여줌

정적 생성

1. 특징

  • 프로젝트가 빌드하는 시점에 html 파일들을 생성하고 모든 요청에 재사용
  • 퍼포먼스를 이유로 Next.js는 정적 생성을 권고
  • 정적 생성된 페이지들은 CDN에 캐시됨
  • getStaticProps / getStaticPaths Method

2. getStaticProps

export async function getStaticProps() {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;
  const res = await axios.get(apiUrl);
  const data = res.data;
  return {
    props: {
      list: data,
    },
    revalidate: 20
    // 20초가 지난 후 접속이 일어나면 파일을 새롭게 생성 (변경 사항이 반영되도록)
  };
}

3. getStaticPaths

// getStaticProps를 통해 다이나믹 라우트 구현 : 개수가 한정적일 때에 해당
export async function getStaticPaths() {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;
  const res = await axios.get(apiUrl);
  const data = res.data;
  
  return {
    paths: data.slice(0, 9).map((item) => ({
      params: {
        id: item.id.toString(),
      },
    })),
    fallback: false,
  };
}

export async function getStaticProps(context) {
  const id = context.params.id;
  const apiUrl = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const res = await axios.get(apiUrl);
  const data = res.data;
  return {
    props: {
      item: data,
    },
  };
}

fallback

  • false : 없는 페이지는 대응해주지 않음(404)
  • true : 없는 페이지일 경우 처음엔 props가 빈 상태로 그려지다 백그라운드에서 정적파일로 HTML과 JSON을 생성한 후 NextJS는 프리렌더링 목록에 추가하여 두번째 접속부터 정적페이지 파일을 사용
    *페이지가 굉장히 많을 경우 build-time이 너무 늘어나 위험
  • 첫 접속시 빈 페이지가 나오는 것을 router.isFallback을 활용해 로딩중을 띄워줄 수 있음
import { useRouter } from "next/router";
import { Loader } from "semantic-ui-react";
const Post = ({ item }) => {
  const router = useRouter();
  // router.isFallback : 화면이 그려지기 전엔 true, 그려진 후 false
  if (router.isFallback) {
    return (
      <div style={{ padding: "100px 0" }}>
        <Loader active inline="centered">
          Loading
        </Loader>
      </div>
    );
  }
  return (
    <>
      {item && (
        <>
          <Head>
            <title>{item.name}</title>
            <meta name="description" content={item.description}></meta>
          </Head>
          <Item item={item} />
        </>
      )}
    </>
  );
};

서버사이드 렌더링

1. 특징

  • 매 요청마다 html 파일들이 생성
  • CDN에 캐시되지 않기 때문에 느릴 수 있으나 항상 최신 상태 유지
  • getServerSideProps Method

2. getServerSideProps

// getServerSideProps를 통해 다이나믹 라우트 구현
export async function getServerSideProps(context) {
  const id = context.params.id;
  const apiUrl = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const res = await axios.get(apiUrl);
  const data = res.data;
  return {
    props: {
      item: data,
    },
  };
}

References

1. 코딩앙마 강의

좋은 웹페이지 즐겨찾기