Next의 Pre-rendering과 함수들

2022. 11. 1. 11:32Web_Programming/Next

Next js의 렌더링 과정을 공부해보면서 간단하게 정리해보았습니다.

SSR과 CSR의 수행 방식을 간단히 살펴보고, Next에서 제공하는 함수들에 대해 알아보겠습니다.


Next의 렌더링을 살펴보기 전에

렌더링 과정에서 수행되는 Hydration에 대해 먼저 알아보려 합니다.

 

Hydration이란 무엇인가?

  • Hydrate는 Server Side 단에서 렌더링 된 정적 페이지와 번들링 된 JS파일을 클라이언트에게 보낸 뒤, 클라이언트 단에서 HTML 코드와 React인 JS코드를 서로 매칭 시키는 과정을 뜻합니다.
  • Next.js Server에서는 Pre-Rendering 된 웹 페이지를 클라이언트에게 보내고 나서, 바로 리액트가 번들링 된 자바스크립트 코드들을 클라이언트에게 전송하는데 이 과정을 Hydrate라고 합니다.
  • ⇒ 그리고 이 자바스크립트 코드들이 HTML DOM 요소 위에서 한번 더 렌더링을 하면서, 각자 자기 자리를 찾아가며 매칭이 됩니다.

이제 Next js의 렌더링인 pre-rendering에 대해 알아보겠습니다.

 

Pre-redendering이란 무엇인가? [SSR]

initial Load  정적 HTML render ⇒ hydration JS 파일 연결 [컴포넌트 초기화]

위와 같은 과정으로 Next는 서버에서 먼저 데이터 변경에 영향이 없는 정적 HTML을 가져와 render 시키고

⇒ 이후에 hydration 이라는 과정을 통해 JS 파일을 연결하여 컴포넌트를 초기화해줍니다.

 

따라서 1) 페이지 첫 로딩이 빠르고, MPA방식으로 페이지마다 HTML이 작성되기에 2) SEO에도 좋다는 대표적 장점이 있습니다.

 

SEO란 무엇인가?
  • 검색엔진 최적화 Search Engine Optimization 
  • 검색을 통해 웹사이트에 연결하도록 돕는 최적화 프로세스
  • SEO는 웹 페이지를 크롤링을 이용해 HTML 기반의 데이터를 수집한다.
  • SPA 방식은 HTML 파일이 1개뿐이고, 렌더링이 되기 전까지 껍데기 html만 있어 SEO에 좋지 않다.
  • MPA 방식처럼 매번 요청마다 HTML 파일이 오는 것이 SEO 관점에서 절대적으로 유리하다.

그렇다면 기본 React에서는 어떻게 렌더링이 진행될까?

 

No-Pre-Rendering [CSR]

DOM 생성 ⇒ JS 수행 ⇒ 렌더

HTML, JS, CSS를 서버로 부터 받아 이후에 모두 브라우저 단에서 처리된다.

 

모두 client단에서 수행하기에 첫 로딩이 느리고 SEO에 좋지 않은 단점이 있습니다.

 

1) 이러한 단점을 해결하고

2) Pre-rendering이후에는 CSR처럼 수행되기에

SSR과 CSR의 장점을 모두 합친 것이 Next를 사용하는 큰 이유가 된다고 생각합니다.


그렇다면 Next의 Pre-rendering방식에 대해 좀 더 살펴보겠습니다.

 

Next는 ServerSideRedering 외에 static Generation도 지원합니다.

Pre-rendering 방식

  • Static Generation: HTML 파일이 빌드 타임에 생성돼서 각 요청에 의해 재사용
    • SSG는 보통 많이 변하지 않는 데이터를 갖는 페이지를 미리 만들어 놓을 때 사용
  • Server-Side-Rendering: HTML 파일이 각 요청이 올 때 생성
    • 요청에 따른 응답될 내용이 때때로 바뀌는 경우 사용

 

Next.js Document에서는 Static Generation을 사용하는 것을 권장합니다.

⇒ Static Generation 방식이 추가 구성 요소 없이 CDN에 의해 고정적으로 페이지를 캐싱 처리를 할 수 있어서 일반 ServerSideRedering 보다 퍼포먼스 면으로 좋다.

 

💡 하지만 상황에 따라 Server-Side-Rendering만이 할 수 있는 요소(외부 요청에 의해 내부 내용이 변하는 페이지)도 있을 수도 있어서, Hybrid 형태로 사용 가능하다고 합니다.


이후에는 Next에서 제공하는 함수에 대해 알아보겠습니다.

getStaticProps

Static Generationg 할 때,

데이터도 미리 빌드 타임에 생성할 수 있습니다.

사용법은 해당 페이지의 같은 파일에 async getStaticProps 함수를 선언해서 export 하면 됩니다.

// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

export async function getStaticProps() {
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

해당 페이지에서 정적으로 사용되는 데이터들은 모두 getStaticProps에서 불러와서 사용하도록 하면 됩니다.

getStaticPaths

Next.js에서는 동적 라우팅 처리(ex: pages/posts/[id]. js)의 id로 들어갈 각 페이지 지정을 getStaticPaths에서 해줄 수 있습니다.

// 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) => ({
    params: { id: post.id },
  }))

// We'll pre-render only these paths at build time.// { fallback: false } means other routes should 404.
return { paths, fallback: false }
}

return : 모든 posts 데이터를 가져와서 각 포스트의 ID 값만 가진 paths 배열 데이터

fallback

false ⇒ 빌드 시점에 없는 요청이면 무조건 404

true ⇒ 요청을 한번 보내고 데이터가 있다면 html을 생성, 없다면 이에 대한 처리를 개발자가 해주어야 함.

 

ex | [{id:1}, {id:2}, {id:3}]를 반환했으면, 동적으로 pages/posts/1, pages/posts/2, pages/posts/3페이지가  빌드 타임 때 생성

 

 

 동적 라우팅 페이지 내에서도 당연히 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

getServerSideProps

빌드 타임 시 말고, 유저가 페이지 서비스에 접속하려고 페이지 요청을 보낼 시에 서버에서 정적 HTML 파일을 생성하는 방법입니다.

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

사용법도 getStaticProps와 동일하고, 이름도 유사하지만,

getServerSideProps는 빌드 타임 때가 아닌, 요청 시마다 동작됩니다.

 

💡 사용 이유

  • 클라이언트에서 하면 데이터 요청 전, 빈 화면을 랜더링
  • getServerSideProps를 사용하여 ⇒ 서버 측에서 pre-render를 해놓고 반환하므로 랜더링 된 결과가 화면에 전부 나타남

 

 

getInitialProps

Next.js 9.3 이전 버전에서는 SSR (Server-Side Rendering)을 위해 getInitialProps만을 사용

이 방식도 Server-Side-Rendering 방식인데, Automatic Static Optimization이 비활성화되어서 권장하지 않는 방식이라고 합니다.

 

Automatic Static Optimization 이란?

미리 빌드 타임에 정적 파일로 생성돼서 CDN 등으로 캐싱돼서 요청 시 사용되는 방식

이로 인해 요청 시마다 항상 정적 파일을 생성하지 않고, 미리 생성되어 캐싱된 파일만 바로 제공하면 되므로 굉장히 빠른 로딩이 가능하다.

 

❗️ getServerSideProps와 getInitialProps를 페이지 내에 선언하게 되면,

해당 페이지가 요청 시마다 동작하게 되므로 Static Optimization이 되지 않는다는 점을 주의

 

 

참고 블로그

Next.js의 Hydrate란?

 

Next.js의 Hydrate란?

Next.js 프레임워크의 동작원리를 제대로 파악하고 있는 개발자라면 Hydrate에 대해선 이미 익숙한 용어일 것이다. 그러나 Next.js의 주요 동작 방식 중 하나임에도, 눈에 잘 띄지 않아 놓치기도 쉬운

helloinyong.tistory.com

Next.js Pre-Rendering(Server-Side-Rendering) 함수 정리

 

Next.js Pre-Rendering(Server-Side-Rendering) 함수 정리

업무 시간에 시간이 붕 떠서,... Next.js Document를 정독했다.. 그래서 Doc 보면서 공부한 내용들을 블로그에 정리해보려고 한다. Hydration Next.js에서는 기본적으로 Page 별로 라우팅 처리가 되어 있다보

helloinyong.tistory.com

 

반응형