본문 바로가기

Study/Next

pre-rendering

data fetching & pre-rendering | React vs. Next

React.js에서 데이터를 받아오는 방식과 문제점은 다음과 같다. 

 

  1. useEffect 내부에서 필요한 데이터를 backend api에게 요청한다. 
  2. 성공적으로 받아온 데이터를 state로 업데이트한다. 
  3. 데이터를 화면에 보여준다. 
  4. 결론 | 사용자는 html 코드와 js 코드를 한 번에 받아오고, js 코드가 실행되면 동적으로 html을 구성한다. 
  5. 문제점
    1. js가 실행되어야 데이터를 받아올 수 있다는 것은, 온전한 페이지를 보여줄 때 까지 시간 지연이 발생한다는 것을 의미한다.
    2. 뿐만 아니라 최초의 html 코드(page source에서 확인할 수 있는 html 코드)에는 동적으로 생성되는 데이터가 포함되어 있지 않기 때문에, SEO에 나쁜 영향을 끼칠 수 있다. 
  6. +) 리액트에서는 fetched data 뿐만 아니라 모든 html 코드가 페이지 소스에 포함되어 있지 않다. 넥스트는 기본적으로 정적으로 구성되는 모든 html 코드를 페이지 소스에 포함한다. 

 

리액트 앱으로 만든 페이지의 page source. <div id="root"> 내부에는 fetched data 뿐만 아니라, 모든 html 코드가 미포함 되어있음.

 

Next.jspre-rendering을 이용해 위와 같은 문제를 해결한다. 

 

  1. 기본적으로, initial load에서 dynamic data가 없는 모든 페이지를 pre rendering 한다. 그 이후에는 이전과 같은 방식으로 client side에서 어플리케이션의 컨텐츠를 동적으로 제어한다. 
    • +) dynamic parameter를 갖는 페이지는 pre rendering 대상이 아니다. 
    • html을 pre rendering 하는 데 필요한 최소한의 js 코드 만이 initial load에 포함된다(동적으로 data를 받아오는 코드는 처음에 포함되지 않는다).
    • 브라우저에 의해 페이지가 load 될 때 그 페이지에 포함된 모든 js 코드재전송하는데, 이를 hydration이라고 하고 ,이 때부터 페이지는 다시 client side에서 제어된다. 
  2. 부가적인 코드를 작성하면, data fetching을 필요로 하는 page도 pre rendering 할 수 있다.
  3. next.js가 미리 렌더링된 페이지(pre-rendered page)를 반환하면 크롤러가 이 페이지의 정보를 수집하기 때문에, SEO에 좋다.
  4. 결론 | 사전에 html 페이지를 완전히 구성하고, 이를 사용자에게 제공한다.
    •  static generation, server side rendering 두 가지 방법을 이용해 pre rendering을 구현할 수 있다. 

static site generation

1) getStaticProps

  1. next.js에게 해당 페이지를 pre-rendering 할 것을 명령하는 메서드라고 할 수 있다. 
  2. 어플리케이션을 build 할 때 pre rendering할 페이지(pre-generate page, html)를 만든다. 
    • build 명령어를 실행한 뒤, .next/server/pages 에서 생성된 페이지(html)를 확인할 수 있다. 
    • start 명령어를 실행하면, 개발용이 아닌  production ready page를 확인할 수 있다. 
  3. 어플리케이션을 deploy 하면 서버에서 1에서 만든  페이지를 CDN의 형태로 cache 한다. 
  4. request가 발생할 때 마다 1에서 만들어진 페이지를 재사용 할 수 있다.  
  5. next.js는 pre rendering 페이지를 만들 때, 성능의 측면에서 static generation을 이용할 것을 추천한다. 
  6. 자주 변하지 않는, 정적인 데이터를 이용해 페이지를 구축할 때 적절하다. 

- incremental static regeneration with revalidate option

  1. revalidate 옵션을 사용하면, ISR을 이용할 수 있다. 
  2. build 할 때 생성된 pre-generate page를 server에서 일정 시간 간격으로 업데이트할 수 있다.
    • page에 필요한 데이터가 변화하는 빈도에 따라 그 시간 간격을 정할 수 있다. 
    • 마지막으로 페이지가 생성된 시간 ~ 현재 request가 발생한 시간 사이의 간격을 확인한다. => 기존에 생성된 page를 반환할지, 새로운 페이지를 생성하고 이를 반환할지 결정한다. 
    • npm start 명령어를 이용해 local에서 production ready page를 확인해 보면, dev 모드에서와 달리, request가 발생하더라도 정해둔 시간이 지나지 않으면 page가 재생성되지 않는 것을 알 수 있다. 

- other options

export async function getStaticProps() {
  // get data from data directory
  
  return {
    props: {
      products: data.products,
    },
    revalidate: 60,
  };
}

- context parameter 

export async function getStaticProps(context) {}

 

  1. context는 다음의 key를 갖는 객체이다. 
  2. params | 현재 url에서 dynamic params의 구체적인 값을 알려 준다. => ex) { productId: 'p1' }  

2) getStaticPaths

  1. dynamic url에 대한 pre-rendering을 구현하려면 getStaticPaths를 사용한다. 
  2. paths | 구체적으로 어떤 경로의 페이지(concrete instances)를 미리 생성해 둘 것인지 지정한다.  
  3. fallback | paths에서 지정하지 않은 segment 경로에 접근했을 때 어떻게 동작할지 지정한다. 
    • false | 404 페이지를 반환한다. 
    • true | server에서 html이 생성되기 전까지 fallback page(loading...)를 렌더링하다가, 생성이 완료되면 그 full page를 반환한다. 한번 접근한 페이지는 pre-renderd page list에 추가되어 재사용된다. 
    • 'blocking' |  server에서 html이 생성될 때 까지 기다렸다가 full page를 반환한다. 마찬가지로, 한번 접근한 페이지는 pre-renderd page list에 추가되어 재사용된다(identical to ssr). 
    • +) true, blocking 옵션은 request가 발생하면, 서버 측에서 그때 그때 html 페이지를 생성한다.  
    • +) true일 때, anchor 태그를 이용해 지정하지 않은 경로에 접근한 경우에는, fallback => full page가 아니라, server side에서 생성되는 페이지를 기다렸다가 full page를 바로 반환한다. 즉 'blocking' 옵션과 같은 방식으로 동작한다. 
    • +) true 일 때, 현재 페이지가 fallback 상태인지 아닌지 확인하려면? 

server side rendering 

  1. static site generation은 어플리케이션을 build 할 때 미리 페이지를 생성한다.
    • 예외적으로 ISR은 지정해 둔 revalidate 시간에 따라 ssr을 이용한다. 
  2. server side rendering은 요청이 발생할 때 마다, 서버 측에서 해당 페이지를 생성한다. 즉, 유입되는 모든 요청에 대해 새로운 페이지가 pre rendering 된다.
  3. 어떤 페이지를 구성하고 있는 data가 자주 변경된다면, 요청이 발생할 때 마다 서버 측에서 해당 page를 rendering 하는 것이 더 낫다. 

getServerSideProps

  1. next.js는 페이지에 request가 발생할 때 마다 getServerSideProps을 실행한다. 
  2. getStatic~과 달리 context parameter에서 req, res 객체에 접근할 수 있다. 
    • request에 함께 attach 되어있는 header, cookie 등에 접근할 수 있고, 요청을 보낸 사람이 누구인지 특정할 수 있다. 
  3. +) getStaticProps와 같은 페이지에서 사용할 수 없다(사전에 렌더링할 페이지를 무엇으로 할 것인지 충돌이 일어남).

client side data fetching

  1. 미리 페이지에 필요한 데이터를 받아 놓는 것이 아니라, 사용자가 페이지에 방문 했을 때 data를 받아오는 것이 더 나은 경우도 여전히 존재한다. => 실시간으로 변화하는 최신 데이터(ex. 주식) 등 
  2.  

example code here

  1. 기존의 data fetching 방식의 문제점 
  2. pre-rendering 
  3. static site generation(SSG)
    1. getStaticProps
      • static page 구축하기
      • incremental static regeneration 설정하기 => revalidate
      • data fetching 실패 시 유용하게 사용할 수 있는 return 객체의 key 살펴보기 => notFound, redirect
      • next.js가 (기본 값으로) 동적 경로를 포함하는 페이지를 pre-rendering하지 않는 이유 
    2. getStaticPaths
      • 동적 경로를 포함하는 페이지 pre-rendering 하기
      • return 객체의 key 살펴보기 => paths, fallback 
  4. server side rendering(SSR)
    1. getServerSideProps
      • getStaticProps와 차이점
      • 동적 경로와 SSR

'Study > Next' 카테고리의 다른 글

optimization with <head> & <image>  (1) 2022.10.18
client side data fetching  (0) 2022.10.17
how useRouter works  (0) 2022.10.09
what is _app.js?  (0) 2022.10.09
file based routing  (1) 2022.10.04