Pre-rendering
기본적으로 Next js는 모든 페이지를 pre-renders 해준다.
즉, Next.js는 클라이언트 측 JavaScript에서 모든 작업을 수행하는 대신
각 페이지에 대해 미리 HTML을 생성한다.
생성된 각 HTML은 해당 페이지에 최소한의 JS 코드와 연결된다.
브라우저에서 페이지를 로드하면 해당 JS 코드가 실행되고, 페이지가 상호작용 하게 된다. ( hydration )
2가지 형태의 pre-rendering
- Static-Generation: HTML은 빌드할 때 생성되며, 각 요청에서 재사용된다.
- Server-side-Rendering: HTML은 매 요청 시에 생성된다.
Static Generation
만약 페이지가 Static Generation를 사용하게 된다면, HTML은 빌드할 때, 생성된다.
운영에서, next build를 실행할 때 페이지 HTML이 생성된다.
이 HTML은 각 요청에서 재사용되며, CDN에 의해 캐시 될 수 있다.
Next.js에서는 페이지를 static 하게 2가지 방식으로 만들 수 있다.
Static Generation without data
다음과 같이, data를 가져올 필요가 없을 때, Next js는 빌드 시 단일 HTML 파일을 생성한다.
function Test() {
return <div>Test</div>
}
export default Test
Static Generation with data
일부 페이지에서는 pre-rendering을 위해 외부 데이터를 가져와야 한다.
두 가지 시나리오가 있으며, 두 가지 다 적용 가능하다.
각각의 경우 Next.js가 제공하는 특수 기능을 사용할 수 있다.
- 페이지 content가 외부 데이터에 따라 다를 때: getStaticProps.
- 페이지 paths가 외부 데이터에 따랄 다를 때,: getStaticPaths. (getStaticProps와 같이 쓰인다)
Scenario 1: Your page content depends on external data
pre-render에서 데이터를 가져오기 위해, Next.js를 사용하면 동일한 파일에서 getStaticProps라는 비동기 함수를 내보낼 수 있다. 이 함수는 빌드 시 호출되며 pre-render시 가져온 데이터를 페이지의 props로 전달할 수 있다.
예시) 블로그 페이지는 블로그 게시물 목록을 가져와야 할 수 있습니다.
function Blog({ posts }) {
// Render posts...
}
// This function gets called at build time
export async function getStaticProps() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts')
const posts = await res.json()
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts,
},
}
}
export default Blog
Scenario 2: Your page paths depend on external data
예를 들어 pages / posts / [id]. js라는 파일을 만들어 ID를 기반으로 한 단일 블로그 게시물을 표시할 수 있는데,
Next.js를 사용하면 동적 페이지 (이 경우 pages / posts / [id]. js)에서 getStaticPaths라는 비동기 함수를 내보낼 수 있다. 이 함수는 빌드 시 호출되며 pre-render 할 경로를 지정할 수 있다.
// This function gets called at build time
export async function getStaticPaths() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => `/posts/${post.id}`)
// We'll pre-render only these paths at build time.
// { fallback: false } means other routes should 404.
return { paths, fallback: false }
}
또한 pages / posts / [id]. js에서 이 ID로 게시물에 대한 데이터를 가져와서 페이지를 사전 렌더링 하는 데 사용할 수 있도록 getStaticProps를 내 보내야 한다.
function Post({ post }) {
// Render post...
}
export async function getStaticPaths() {
// ...
}
// This also gets called at build time
export async function getStaticProps({ params }) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
// Pass post data to the page via props
return { props: { post } }
}
export default Post
Server-side Rendering
Server-side Rendering를 사용하게 된다면, 페이지는 각 요청에서 HTML을 생성하게 된다
페이지에 서버 측 렌더링을 사용하려면 getServerSideProps라는 비동기 함수를 내 보내야 한다. 이 함수는 모든 요청에서 서버에 의해 호출된다.
예를 들어, 페이지에서 자주 업데이트되는 데이터 (외부 API에서 fetch)를 pre-rendering 한다고 이 데이터를 가져와서 아래와 같이 Page에 전달하는 getServerSideProps를 작성할 수 있다.
function Page({ data }) {
// Render data...
}
// This gets called on every request
export async function getServerSideProps() {
// Fetch data from external 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
정리
- Static Generation (Recommended): The HTML is generated at build time and will be reused on each request. To make a page use Static Generation, either export the page component, or export getStaticProps (and getStaticPaths if necessary). It's great for pages that can be pre-rendered ahead of a user's request. You can also use it with Client-side Rendering to bring in additional data.
- Server-side Rendering: The HTML is generated on each request. To make a page use Server-side Rendering, export getServerSideProps. Because Server-side Rendering results in slower performance than Static Generation, use this only if absolutely necessary.
Next js 공식 홈페이지에서는 Static-Generation이 페이지를 한 번 빌드하고 CDN에서 제공할 수 있으므로 가능하면 정적 생성 (데이터 포함 및 제외)을 사용하는 것이 좋다고 추천한다.