Published on

nextjs app router에서의 캐싱

Authors
  • avatar
    Name
    Yanguk
    Twitter

nextjs app router 방식에서는 최적화를 위한 내부에서 다양한 캐싱이 진행된다.
이러한 캐싱은 어떤게 있는지 알아볼려고 한다.

캐싱의 종류

MechanismWhatWherePurposeDuration
Request Memoization함수의 반환 값ServerReact Component 트리에서 데이터를 재사용요청 라이프사이클 동안
Data Cache데이터Server사용자 요청 및 배포 간 데이터 저장지속적 (재검증 가능)
Full Route CacheHTML 및 RSC 페이로드Server렌더링 비용 절감 및 성능 향상지속적 (재검증 가능)
Router CacheRSC 페이로드Client네비게이션 시 서버 요청 감소사용자 세션 또는 시간 기반

일단 표에서 서버 수행되는 캐싱이 3가지가 있고,
클라이언트에서 수행되는 캐싱은 하나뿐이다.

출처: nextjs공식 홈페이지 (https://nextjs.org/docs/app/building-your-application/caching)

Request Memoization

  • 서버컴포넌트에서만 수행되는 동작
  • 페칭한걸 캐싱해서 동일한 요청은 한번만하는 컨셉

예시를 살펴보자.

const getItem = async () => {
  // `fetch` 함수는 자동으로 메모이제이션되고 결과는
  // 캐싱됩니다.
  const res = await fetch('https://.../item/1')
  return res.json()
}

async function Item1() {
  const item = await getItem()

  return <div>...</div>
}

async function Item2() {
  const item = await getItem()

  return <div>...</div>
}

export default async function Page() {
  return (
    <div>
      <Item1 />
      <Item2 />
    </div>
  )
}

Page안에서 각각의 컴포넌트가 페칭을 하고 있는데, 같은 페칭이라서 페칭은 한번만 수행이 된다. 클라이언트에서의 tanstack-query와 비슷한 컨셉이라고 느껴졌다.

추가적으로...

  • 메모이제이션은 fetch 요청의 GET 메서드에만 적용됨
  • 렌더링이 끝나면 메모리가 리셋되고 메모이제이션된 항목은 삭제됨
  • nextjs의 기능이 아닌 react의 기능임

개발자로써 활용할 수 있는 부분은?

  • 클라이언트 tanstack-query 쓰던거 처럼 서버컴포넌트에서도 가능한 점 이랄까?
  • 이전에 상위에서 한번 페칭해서 props 드롤링하는 행위는 안해도 된다는게 개발상 편의가 있을거 같고, 컴포넌트 분리가 수월 해질 것 같다.

Data cache

  • 서버컴포넌트에서만 수행되는 동작
  • nextjs에는 내장 데이터 캐시가 있는데 여기에 저장이 됨
  • fetch 사용시 옵션으로 제어 및 next.revalidate로 제어
// 최대 한 시간마다 재검증
fetch('https://...', { next: { revalidate: 3600 } })

// 영구 캐싱
fetch('https://...', { cache: 'force-cache' })

개발자로써 활용할 수 있는 부분은?

  • 변하지 않는 정적 데이터는 force-cache으로 페칭해서 사용하면 될 것 같다.

Full route cache

  • 서버컴포넌트에서만 수행되는 동작
  • 기존의 SSG 방식과 동일함
  • 정적 라우팅만 적용 되고, 다이나믹 라우팅은 적용이 불가함

build시에 static한 페이지라고 한다면 이는 캐싱이 된다.
블로그와 같이 인증 요소도 없고 빌드타임에 정적페이지로 생성이 가능한 시스템에서 활용될 수 있는 요소 인 것 같다.

개발자로써 활용할 수 있는 부분은?

  • 정적 페이지는 나눠서 개발하도록 신경써야겠지만 자연스럽게 개발하여도 기본적으로 build시에 알아서 다 만들어지니까 하던데로 하면 될 것 같다.

Client-side router cache

  • 클라이언트 컴포넌트에서만 수행되는 동작

다음 링크에 호버시 다음페이지를 미리 페칭한다던지,
뒤로가기에 존재했던 페이지를 캐싱을 해놔서 뒤로가기시 화면이 바로 보인다던지 정도의 케이스가 될 것 같다.

개발자로써 활용할 수 있는 부분은?

  • nextjs의 Link 컴포넌트를 적절히 활용하는 방법이 있을거 같다.
  • router.prefetch로 다음페이지를 미리 가져오는것도 가능할 것 같다.

마무리

이미 예상했던 동작들이라 생각보단 뭐 별건 없었는데, 막연히 nextjs에서 캐싱해서 최적화를 하고있다... 라고 아는것보단 한번 짚고 넘어 가는게 좋을 것 같아서 알아보았다.

그리고 nextjs는 문서가 참 정리가 잘되어있는거 같다. 👍