• Feed
  • Explore
  • Ranking
/

    NextJS 15 ‘use cache’

    G
    Ganymedian
    2024.11.04
    ·
    4 min read

    NextJS 15 ‘use cache’

    NextJS 15 에서, fetch 를 이전 버전처럼 사용하면 에러가 발생하는데요..

    NextJS 15 버전 부터는 fetch 의 캐시 정책을 명시적으로 표현해줘야만 합니다.

    이 때 ‘use cache’ 가 사용됩니다.

    .

    fetch 모듈에 대해서, 데이터를 캐싱 할 것인가 아닌가에 따라 두가지 구현 방식으로 갈라집니다.

    1. fresh data for every request : <Suspense>

    2. cached data : 'use cache'

    .

    .

    Fresh Data for every request

    모든 요청에서 fresh data 를 받아와야 할 때는, 해당 컴포넌트를 Suspense 로 감싸줍니다.

    // fresh data for EVERY requests..
    // 이제 Next 가 자체적으로 캐시를 오버라이드하지 않는다. fetch 는 캐시되지 않는다.
    export function Notice() {
      const data = fetch(...)
      return (...data)
    }
    
    // 이제는 Suspense 가 없으면 에러를 뱉는다.
    export default function Page() {
      return(
        <Suspense fallback={...loading}>
          <Notice />
            {... some other Data}
        </Suspense>
      )
    }
    

    .

    .

    Cached Data

    Cache 와 Static Yuji 가 필요할 때, 'use cache' 를 선언주고 Suspense 를 제거합니다.

    // Cache 해야 할 때
    'use cache'
    
    // 'use cache' 디렉티브에 따라 cache 는 캐싱된다. 
    export function Notice() {
      const data = fetch(...)
      return (...)
    }
    
    // Notice 컴포넌트가 SSG 가 되는지는 아직 확인하지 못했다. 
    export default function Page() {
      return(
        <Notice />
        (...other Data)
      )
    }
    

    SSG 같은 컴포넌트 단위의 Static-Component-Generation 과 'use cache' 의 관계와 차이를 아직 분명히 확인하지 못했습니다.

    사이트 내에서 100만개의 캐시가 발생할 수도 있기 때문에, 관리를 위해선 Static Component 가 될 것 같지만, 펑션 단위의 ‘use cache’ 도 허용되는 것을 봐선 그렇지 않을 것 같기도 합니다. 때가 되면 저절로 알게 되겠죠.

    .

    .

    Cache Handling for Route Segments

    Route Segment 들은, use cache 와 Suspense 가 믹스되는 방식으로 중첩구조를 이루게 되는데, 특히 layout.tsx 에서는 use cache - Static 이 유용합니다.

    // 이제 layout 은 캐싱 되고, children 에 대해 각각의 cache segment 가 할당된다.
    // ContextProvider 들과 NavBar, Footer 는 Static 고정되고, 
    // Navigation 은 children 내에서만 각각의 Route Segment 정책에 따라 이동하고 캐싱된다.
    'use cache'
    export default function RootLayout({
      children
    }: Readonly<{
      children: React.ReactNode
    }>) {
      return (
        <html
          lang="en"
          suppressHydrationWarning={true}>
          <body
            className={inter.className}
            suppressHydrationWarning={true}
            suppressContentEditableWarning={true}>
            <AuthProvider>
              <NavigationGuardContextProvider>
                <ThemeProvider
                  defaultTheme="dark"
                  storageKey="ganymedian-ui-theme">
                  <RootFrame>
                    <NavBar />
                    <MainFrame>{children}</MainFrame>
                    <Footer />
                  </RootFrame>
                  <Toaster />
                </ThemeProvider>
              </NavigationGuardContextProvider>
            </AuthProvider>
          </body>
        </html>
      )
    }**
    

    .

    .

    Cache Stale & Revalidate

    이건 아직 unstable 버전이라고 합니다… Next Conf 에 납품 기일을 못 맞춘 팀이 있었나본데.. 감정이입이 되는군요.

    // cacheTag : Cache Id 
    // cacheLife: Cache Life for Cache Id
    import { unstable_cacheTag as cacheTag, unstable-cacheLife as cacheLife } from 'next/cache'
    
    async function getNotice() {
      'use cache'
      const data = fetch(...)
    
      cacheTag('cache-control-' + data.id)
      cacheLife({
        revalidate: 60,
        expire: 3600,
      stale: 10,
      })
    
      return ({...data})
    }
    
    export default function Page() {
      return(
        <div>
          {await getNotice()}
          (...other Data)
        </div>
      )
    }
    

    .

    .

    세줄 요약

    1. NextJS.15 에서 fetch 가 사용될 때, ‘use cache’ 를 명시적으로 표현해줘야 한다.

    2. Cache 하지 않을 때 : <Suspense>

    3. Cache 할 때 : 'use cache'

    'use client' , 'use server' 못지 않게 'use cache' 도, 중요한 디렉티브 키워드가 되었습니다.

    .

    -끗-

    .