- Published on
nextjs app router에서의 캐싱
- Authors
- Name
- Yanguk
nextjs app router 방식에서는 최적화를 위한 내부에서 다양한 캐싱이 진행된다.
이러한 캐싱은 어떤게 있는지 알아볼려고 한다.
캐싱의 종류
Mechanism | What | Where | Purpose | Duration |
---|---|---|---|---|
Request Memoization | 함수의 반환 값 | Server | React Component 트리에서 데이터를 재사용 | 요청 라이프사이클 동안 |
Data Cache | 데이터 | Server | 사용자 요청 및 배포 간 데이터 저장 | 지속적 (재검증 가능) |
Full Route Cache | HTML 및 RSC 페이로드 | Server | 렌더링 비용 절감 및 성능 향상 | 지속적 (재검증 가능) |
Router Cache | RSC 페이로드 | 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는 문서가 참 정리가 잘되어있는거 같다. 👍