본문 바로가기
배움 기록/Next.js

[Next.js] Static / Dynamic rendering 과 caching 기능 사용하기 (App Router ver.)

by dygreen 2023. 10. 5.

📌 Static / Dynamic rendering

Next.js 는 아래 2개의 방식으로 웹페이지를 유저에게 보내준다. (Next.js 가 2개 방식을 자동으로 구분해줌)

Static rendering

- Next.js 에서 페이지를 하나 만들면 기본적으로 Static rendering 식으로 페이지를 보여준다.

- npm run build 시 html 페이지들을 만들고, 유저가 접속할 때 마다 이 페이지를 보내준다.

- 페이지 안에 별 기능이 없다. (→ 따라서, 매번 html 페이지를 새로 만들 필요가 없음)

- Next.js 옛날 버전의 SSG 개념으로 보면 된다.

 

Dynamic rendering

- 페이지 안에 아래와 같은 것을 사용한다면 dynamic rendering 식으로 페이지를 보여준다.

  • fetch('/URL', {cache: 'no-store'})
  • useSearchParams(), cookies(), headers()
  • [dynamic route]

- npm run build 로 html 페이지를 만들어놨지만, 유저가 접속할 때마다 html 페이지를 서버에서 다시 그려 페이지를 보내준다.

 

 

강제로 Static / Dynamic rendering 을 설정하려면

npm run build 시 터미널

▲ npm run build 시 'λ 표시' 와 'ㅇ 표시' 가 나오는데

λ 표시Dynamic rendering, ㅇ 표시Static rendering 을 해준다는 의미이다.

 

 

강제로 설정을 바꾸려면 페이지 상단에 아래 변수를 추가하면 된다.

export const dynamic = 'force-dynamic' 

export default function Page () {
  (생략)
}
  • Static rendering 을 하고 싶으면, 'force-static'
  • Dynamic rendering 을 하고 싶으면, 'force-dynamic'
  • default'auto'

 

📌 Caching 기능 사용해보기

Dynamic rendering 으로 동작하는 페이지가 많으면 아무래도 서버 부담이 심해질 수 있다.

이 경우 caching 기능을 이용하여 Dynamic rendering 시 서버 자원을 절약할 수 있다.

 

Next.js 에서는 1. GET 요청 결과 캐싱 2. 페이지 캐싱 기능이 있다.

* server component 안에서만 캐싱 기능 사용 가능

 

1. GET 요청 결과 캐싱하기

1-1. npm run build 시 가져온 결과 캐싱

export default async function Page() {
  let result = await fetch('/URL', { cache: 'force-cache' })
}

▲ 위와 같이 작성하면 fetch 요청을 할 때마다 서버에서 데이터를 새로 가져오는 것이 아니라

npm run build 시 가져온 결과를 저장해두고 그걸 가져온다.

( 다시 npm run build 하기 전까지 캐싱된 걸 보여준다. )

따라서 훨씬 빠르게 데이터를 가져올 수 있다.

 

* 위와 같이 작성을 하지 않아도, default 값으로 'force-cache' 이 설정되어 있음

 

 

1-2. 특정 시간 동안 캐싱

fetch('/URL', { next: { revalidate: 60 } })

▲ 위와 같이 작성하면, 요청 결과를 60초 동안 저장하고 사용한다.

60초가 지나면 다시 /URL 로 새로 요청해서 결과를 가져오고 캐싱해준다.

 

 

1-3. 캐싱 기능 사용 안하기

fetch('/URL', { cache: 'no-store' })

▲ 위와 같이 작성하면 매번 저 코드를 읽을 때마다 서버로 요청해서 데이터를 새로 가져온다.

실시간 데이터가 중요할 때 사용하면 좋다.

 


2. 페이지 캐싱 기능 (= 예전 Next.js 의 ISR 기능)

Next.js 에서 revalidate 옵션을 사용하면, 페이지 단위로 캐싱이 가능하다.

export const revalidate = 60;

export default function Page() {
  (생략)
}

▲ 페이지 파일 위쪽에 revalidate 변수를 만들고 원하는 초 단위를 집어 넣으면, 해당 페이지를 그 시간 만큼 캐싱할 수 있다.

따라서, 페이지 접속 시 60초 동안은 아무리 새로고침 해도 미리 캐싱된 페이지를 보여준다.

60초가 지나면 페이지를 재생성해서 캐싱해준다.

* (유저가 없어도 60초 마다 페이지를 재생성 하는 것이 아니라) 유저가 접속을 해야 60초 마다 페이지를 재생성해준다.

 

이를 통해 Static rendering (= SSG) 의 성능상 이점을 챙기면서도 유저에게는 업데이트된 내용을 제공해줄 수 있다.

 

 

 

60초가 지나기 전에 페이지를 강제로 새로 만들라고 명령할 수도 있다.

 

► On-Demand Revalidation

// api handler
export default async function handler(req, res) {
  try {
    // this should be the actual path not a rewritten path
    // e.g. for "/blog/[slug]" this should be "/blog/post-1"
    await res.revalidate('/list')
    return res.json({ revalidated: true })
  } catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send('Error revalidating')
  }
}

예를 들어, 60초 마다 페이지를 재생성하게 설정해 놓은 경우가 있다.

그러면 유저가 해당 페이지에서 글을 하나 작성해도 60초 간은 새로운 글이 안보일 수 있다.

이 경우 On-Demand Revalidation 기능을 사용하면, 직접 지정한 페이지의 캐시를 새로 생성하라고 할 수 있다.

 

위 코드는 /list 페이지는 기본적으로 60초 마다 페이지를 재생성 하는 것인데,

해당 페이지에서 api 를 요청했을 경우에 (60초 이전에도) 캐시를 새로 생성하도록 설정한 것이다.

이렇게 하면, 글을 작성하는 api 를 요청하면 작성한 새로운 글이 바로 보일 수 있게 된다.

728x90

댓글