(번역)도대체 SSG가 뭘까요? Next.js로 설명하는 정적 사이트 생성

강엽이·2022년 4월 2일
12
post-thumbnail

원문 : https://dev.to/anshuman_bhardwaj/what-the-heck-is-ssg-static-site-generation-explained-with-nextjs-5cja

만약 여러분이 웹 개발자이고 세상과 담을 쌓고 살고 있는 것이 아니라면, "SSG"라는 유행어를 접해봤을 것입니다.
다음 5분동안 우리는 "SSG"에 대한 기초를 배울 것입니다.

SSG(Static Site Generation)란 무엇일까요?

정적사이트 생성(SSG, Static Site Generation)은 빌드 시 리액트 앱을 HTML로 미리 렌더링합니다.

좀 더 자세히 살펴보죠. 이상적으로 리액트 앱은 클라이언트 측에서 렌더링 됩니다. 즉, 사용자의 브라우저는 먼저 자바스크립트 번들을 다운로드 한 다음 사용자가 컨텐츠를 보기도 전에 다운로드한 자바스크립트 번들을 실행합니다. 꽤 느릴꺼 같죠? 실제로 느립니다.

HTML로 사전 렌더링을 한다는 것은 리액트 Component를 HTML 파일로 변환하고 HTML 파일을 클라이언트에 전송하여 많은 처리나 대역폭 사용 없이 사용자에게 빠르게 표시할 수 있음을 의미합니다.

"그건 서버 사이드 렌더링 아닌가요?"라고 궁금할 수 있습니다.

네, 맞습니다. SSG의 정적(Static)은 SSR 처럼 전체 프로세스가 각 사용자 요청에 수행되는 것이 아닌 빌드 시간에 수행됩니다. 그렇기 때문에 SSG가 서버 사이드 렌더링보다 훨씬 더 빠릅니다.

즉, SSG는 빌드 시 리액트 앱에서 HTML 페이지를 만들기 때문에 모든 요청에 대해 HTML 페이지를 작성할 필요가 없으며 클라이언트 사이드의 브라우저에서도 HTML 페이지를 작성할 필요가 없습니다.

왜 SSG가 필요할까요?

SSG는 특정 사용 사례를 제공하기 위해 존재하며, HTML로 리액트에 내장된 동적 페이지를 제공합니다.

이점이 뭐냐고 물어보셨죠?

  • SEO: 검색 엔진 최적화는 크롤러가 페이지를 쉽게 인덱싱 할 수 있도록 하기 때문에 SSG를 수행하는 최고의 이점 중 하나입니다.
  • 속도: 짐작할 수 있듯이 브라우저가 사전에 많은 처리를 하지 않아도 되기 때문에 HTML 페이지를 제공하는 것이 사용자에게 훨씬 더 빠른 속도를 제공합니다. 사전 렌더링을 통해 브라우저는 HTML을 쉽게 가져와 바로 렌더링 할 수 있습니다.
  • CDN을 사용한 캐싱: HTML 페이지를 구축해놓으면, CDN 캐싱이 매력을 발휘할 수 있습니다. 페이지는 글로벌하게 사용자에게 더 가까이 저장되므로 훨씬 빠르게 엑세스할 수 있습니다. 모든 요청은 서버가 페이지를 렌더링할 때까지 기다릴 필요가 없으며 CDN에서 페이지를 수신하기만 하면 되기 때문에 계산 리소스와 비용을 절약할 수 있습니다.

사용 사례

빌드 시에 페이지를 렌더링 할 수 있는 한, 어떠한 시나리오에서도 SSG를 사용할 수 있습니다. SSG의 인기있는 사용 사례는 다음과 같습니다.

  • 마케팅 웹사이트
  • 블로그 및 문서 (내 블로그 등)
  • 포트폴리오 웹사이트

팁: SSG를 사용해야 하는지 여부를 쉽게 알 수 있는 방법은 "사용자 요청 전에 페이지를 미리 렌더링 할 수 있습니까?"라고 질문 하는 것입니다. 만약 답이 "예"인 경우 "Static Generation"을 선택할 수 있습니다.

SSG에서의 Next.js 사용

Next.js를 사용하여 정적 페이지를 작성하는 것은 간단합니다. 이것은 다른 페이지를 작성하는 것과 거의 비슷하게 기능합니다. 즉, pages 디렉토리에 새 파일을 작성하는 것입니다.

정적 경로의 정적 페이지

먼저 정적 경로 ./pages/first-ssg.tsx를 만듭니다.

페이지는 빌드 시 렌더링되므로 렌더링 전에 Next.js가 모든 데이터를 가져 와야 합니다. Next.js는 빌드 시 실행할 페이지에서 내보낸 getStaticProps 메서드를 찾습니다. 이 메서드는 Page 컴포넌트로 전달 되는 props 키를 가진 객체를 반환해야 합니다.

getStaticProps를 사용하여 페이지를 렌더링하는 데 필요한 정보를 가져옵니다. 예를 들어 회사 소개 페이지를 만드는 경우 getStaticProps를 사용하면 API 엔드포인트에서 회사 세부 정보를 가져올 수 있습니다.

// ./pages/first-ssg.tsx
import type { NextPage } from "next";

export async function getStaticProps() {
  // get all the data needed for rendering the page
  const data = await fetchPageData();
  return {
    props: { data },
  };
}

const FirstSSG = ({ data }) => {
 return (
      <main>
        {/* more html content */}
      </main>
 )
}

export default FirstSSG;

주의: getStaticProps는 요청 시간이 아닌 빌드 시간에 실행되므로 들어오는 요청(쿼리 매개 변수, HTTP 헤더 등)에 엑세스 할 수 없습니다.

동적 경로의 정적 페이지

동적 경로 ./pages/[id].tsx를 작성합니다.

페이지의 특정 데이터를 위한 getStaticProps와는 별도로 Next.js는 이 경로에 대해 가능한 모든 경로를 파악해야 합니다. 왜냐하면, Next.js는 빌드 시 이러한 경로에 대한 페이지를 렌더링해야 하기 때문입니다.

이를 위해 Next.js에서는 빌드 시 동적 루트에 대해 가능한 모든 경로를 나열하는 getStaticPaths 메서드가 필요합니다. 예를 들어 동적 블로그 페이지인 경우 사용 가능한 모든 블로그를 경로로 나열해야 합니다.

getStaticPaths에서 반환되는 paths에는 getStaticProps로 전달되는 params 객체가 포함되어 있습니다. params를 사용하여 경로에 대한 데이터를 전달할 수 있습니다(예: 블로그 slug 또는 id). 나중에 getStaticProps에서 페이지에 대한 데이터를 가져오는데 사용할 수 있습니다.

// ./pages/[id].tsx
import type { NextPage } from "next";

export async function getStaticPaths() {
  return {
    paths: [
      { params: { ... } }
    ],
    fallback: // true or false or 'blocking', to be discussed later
  };
}

export async function getStaticProps({ params }) {
  // 페이지를 렌더링하는 데 필요한 모든 데이터를 가져옵니다.
  const data = await fetchPageData(params);
  return {
    props: { data },
  };
}

// page layout
const FirstSSG = ({ data }) => {
 return (
      <main>
        {/* more html content */}
      </main>
 )
}

export default FirstSSG;

Next.js를 사용하여 정적 웹사이트를 구축하기 위해 필요한 것은 이것뿐입니다.
모든 게 아름다울 수는 없습니다. 그렇죠? 몇가지 함정들에 대해 이야기해 봅시다.

함정

  1. 이 접근법의 가장 큰 결점 중 하나는 빌드 시간입니다. 수천 개의 페이지가 있는 경우 모두 빌드되는데 많은 시간이 걸립니다. 이를 회피하기 위해 사용할 수 있는 Incremental Static Regeneration(ISR)fallback 속성이 있습니다. 이에 대한 내용은 아래에서 설명하고 볼 수 있습니다.
  2. 발생할 수 있는 또 다른 문제는 오래된 페이지입니다. 빌드 시 페이지 데이터를 가져오기 때문에 시간이 지나면 최신의 데이터가 아닐 수 있습니다. 따라서 데이터가 최신인지 확인하기 위해 빌드를 예약하거나 특정 간격으로 트리거해야 할 수 있습니다. 이 문제는 Incremental Static Regeneration(ISR) 으로도 해결할 수 있습니다. 단, 이 경우 이 루트에서는 정적 페이지가 아닌 서버 사이드 렌더링을 고려해야 합니다.

fallback 옵션

앞에서 설명한 바와 같이 getStaticPaths에서 반환할 수 있는 폴백 옵션이 있으며 getStaticPaths에서 반환되는 경로 목록에 없는 경로에 사용됩니다.

fallback 옵션은 빌드 시 렌더링된 경로를 재생성하거나 업데이트하지 않고 빌드 시 사전 렌더링되지 않은 경로에서만 작동합니다.

fallback 옵션은 수천 페이지의 앱에 매우 유용하며, 빌드 시간을 단축하면서 사용자 경험을 최대한 유지 할 수 있습니다.

Next.js를 사용하는 이유

저는 Next.js에서 다음과 같은 두 가지 옵션을 제공하므로 선호합니다.
1. 서버 사이드 렌더링
2. 정적 사이트 생성(SSG)

그래서 두가지 옵션 중 원하는 방향과 맞게 선택하여 개발할 수 있습니다.

또한, 무료로 엣지 캐싱 및 CI/CD를 사용할 수 있는 Vercel 클라우드 플랫폼과 뛰어난 통합(Integration)도 제공합니다.

이것으로 끝입니다. 곧 Incremental Static Regeneration(ISR)에 관련된 다른 글을 쓸 예정입니다. 이 글이 도움이 되길 바랍니다! 피드백이나 질문이 있으시면 언제든지 아래의 코멘트 남겨주세요. 비슷한 글이 필요하시면 트위터를 팔로우 해주세요.

원문은 https://dev.to 에 2022년 3월 21일 게시되었습니다.

🚀 한글로 된 프런트엔드 아티클을 빠르게 받아보고 싶다면 Korean FE Article(https://kofearticle.substack.com/)을 구독해주세요!

profile
FE Engineer

1개의 댓글

comment-user-thumbnail
2023년 8월 8일

잘봤습니다 :)

답글 달기