💡 SSG: 페이지는 사용자 요청과 관계없이 빌드 프로세스 중에 사전 빌드됩니다. 서버는 미리 HTML 페이지를 생성하고, 생성된 파일은 정적 자산으로 제공됩니다.
Next.js에서 제공하는 기능이기도 하며, 전체 사이트를 다시 빌드할 필요없이 페이지별로 정적 생성을 사용할 수 있게 해준다.
Next.js allows you to create or update static pages after
you’ve built your site. Incremental Static Regeneration (ISR)
enables you to use static-generation on a per-page basis,
without needing to rebuild the entire site.
With ISR, you can retain the benefits of static while scaling to millions of pages.
즉, 정적생성으로 미리 만들어놓은 사이트들도 필요하다면 업데이트가 가능하다.
Next.js 12 → Next.js 13 달라진 점 (App router, Data fetching)
💡 Next.js 13의 앱 라우터에서는 `getStaticProps`를 지원하지 않는다**The new data fetching in Next.js 13 is built on top of the fetch() Web API and akes use of async / await in Server Components.
Now, instead of using
getServerSideProps()
andgetStaticProps()
, all fetched data is static by default, meaning it's rendered at build time.
Next.js 13에서 데이터를 가져오는 새로운 방식은 fetch 웹 API 위에 구축되었고, 서버 컴포넌트에서 async/await
을 사용한다.
이제 getServerSideProps
와 getStaticProps
를 사용하는 대신, 가져온 모든 데이터는 기본적으로 정적이며, 빌드 시에 렌더링된다.
💡 빌드 시에 렌더링하면 실시간으로 변경되는 데이터들은 데이터를 업데이트 못하지 않나? fetch의 옵션으로 해결!
fetch 옵션 객체를 확장해서 각 요청마다 자체 캐싱 및 재검증 규칙을 설정할 수 있도록 한다.
{next: revalidate}
옵션을 사용하면, 정적인 데이터를 설정된 간격으로 새로고침하거나 백엔드에서 변경이 있을 때마다 새로고침 할 수 있다.{cache: no-store}
옵션을 사용할 수 있습니다.➡️ 정리하면, 이전에 쓰던 서버 사이드 API 대신에 fetch()
를 사용하면 되고, fetch의 옵션 객체를 이용해 이전의 서버 사이드 API와 같은 기능을 하게 할 수 있다.
{ cache: 'force-cache' }
: 캐시를 강제한다는 뜻으로 정적 사이트(SSG)로 만든다. (getStaticProps
대체)next: { revalidate: 10 }
} : 10초마다 캐시를 갱신한다는 뜻으로 10초 후에 새로운 요청이 오면 페이지를 새로 생성한다. (revalidate 옵션이 있는 getStaticProps
대체[ISR]){ cache: 'no-store' }
: 모든 요청에서 최신 데이터를 받아온다. 즉, 항상 서버 사이드 렌더링한다. (getServerSideProps
대체)Data Fetching: Fetching, Caching, and Revalidating
[13 이전 버전 ]
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
/*getStaticPaths*/
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
const paths = posts.map((post) => ({
params: { id: post.id },
}))
return { paths, fallback: 'blocking' }
}
/*getStaticProps*/
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
revalidate: 10,
}
}
export default Blog
getStaticPaths
build
시간에 정적 생성할 경로들을 getStaticPaths
를 이용해 전달 받는다.
fallback: 'blocking'
옵션은 build
시간에 만들어지지 않은 경로는 SSR처럼 요청시 새롭게 생성된다는 의미이다.
getStaticProps
해당 경로들에 대해서만 정적생성을 진행한다. 여기서 revalidate: 10
옵션이 추가되어 있는데, 이는 해당 페이지로 어느 사용자가 진입한 이후 10초 후에 해당 페이지에 대해서 정적생성을 진행한다는 의미이다. 이때 정적 생성된 페이지를 통해 다음 사용자에게 업데이트된 내용이 제공된다.
revalidate: 60
의 경우
ISR 장점
SSR
과 달리 페이지가 즉시 제공되며(fallback page
), 빠른 경험으로 사용자 경험도 좋아진다.
ISR 단점
페이지 디자인에 따라 첫번째 의미있는 페인팅을 지연시킬 수도 있다.
Data Fetching: Fetching, Caching, and Revalidating
next.js는 backend에서 application 을 pre-render 함
non interactive 한 HTML 파일로 바꿈
사용자가 웹사이트에 도착하면 HTML 전달
프레임워크와 React.js를 initialize
use client 명령어를 가진 component가 hydrate 됨 (interactive)
hydration은 우리가 받은 HTML 위에서 React application을 실행한다는 뜻
SSR 과 SSG는 pre-rendering이라고도 불림
next.js에서는 기본적으로 모든 페이지를 미리 렌더링
사용자의 기기에서 가 모든 일을 처리하는 대신 서버에서 먼저 HTML 파일을 생성하기 때문에, 렌더링 작업이 진행되는 동안 사용자에게 해당 페이지에 필요한 HTML 화면이 보여진다
클라이언트가 받는 웹페이지는 단순히 웹 화면을 보여주기 위한 HTML 일 뿐이고, 동작에 필요한 JS 요소는 없음
특정 JS 모듈 뿐 아니라 단순 클릭과 같은 이벤트들이 각 웹 페이지의 DOM 요소에 적용되어 있지 않은 상태의 페이지가 전송
Next.js 서버에서는 Pre-Rendering 된 웹 페이지를 클라이언트에게 보낸 뒤, 바로 React가 번들링 된 JS 코드들을 Chunk 단위로 클라이언트에게 전송한다.
그리고 이러한 JS 코드들이 이전에 전송된 HTML DOM 요소 위로 리렌더링 되는 과정 속에서 자기 자리를 찾아 매칭된다.
이러한 과정을 "Hydration"이라 부른다!