nahuel.luca()

Small explanation about the Cache in NextJS

We talk about NextJS and the differents ways to cache and manage data in our app.

Static and Dynamic rendering

đź’ˇ Static routes are cached by default, whereas dynamic routes are rendered at request time, and not cached.

Static Rendering

What happens if we have the following code:

export default function Page() {
  return (
    <div>
      <h1>App Router</h1>
      <p>{Date.now()}</p>
    </div>
  );
}

This code is evaluated when the application is being built, so it does not change even if the page is refreshed. This is because this code is pre-rendered and nothing tells the component that it needs access to the information on demand.

One time the component is render in the build time or after execute data revalidation the result is cachend and pushed to the CDN

How to make a RSC dynamic?

We can use cookies(), headers() and noStore(), cookies() and headers() are dynamic functions so when these functions are used the path becomes dynamic at the time of the request. The noStore() function does not cache the RSC so it makes it dynamic.

import {cookies} from "next/headers";

export default function Page() {
  cookies(); // headers() noStore()

  return (
    <div>
      <h1>App Router</h1>
      <p>{Date.now()}</p>
    </div>
  );
}

How NextJS caching data?

đź’ˇ By default, Next.js will cache as much as possible to improve performance and reduce cost.

these are the different paths to cache in your NextJS App:

Request Memoization

With fetch API you can call the same function and get the same data in differents places in react component tree, because NextJS use fetch api and automatically memoize requests that have the same URL and options.

Data Cache

💡 Next.js has a built-in Data Cache that persists the result of data fetches across incoming server requests and deployments.

Any request that use fetch is cached by default for NextJS.

Duration The Data Cache is persistent across incoming requests and deployments unless you revalidate or opt-out.

Revalidating We have 2 ways to revalidate data:

What if difference between Data Cache and Request Memoization?

Both mechanism are similiar made a GET request and if data are cached return this and if not cached made request to the data source.

The Data Cache is persistent across incoming requests and deployments, whereas memoization only lasts the lifetime of a request. Memoization reduce de duplicate request in the same render pass that have to cross the network boundary from the rendering server to the Data Cache server. Data cache reduce the number of requests made to our origin data source.

Full Route Cache

Routes in NextJS are render and caches automatically at build time. This makes our web more faster because serve the cached route instead of rendering on the server for every request.

How Full Route Cache works?

  1. React Rendering on the Server: In first place react render server components in one format that is oprimized for streaming (React Server Component Payload). Then NextJS use that and Client Component JavaScript instructions to render HTML on the server.

    đź’ˇ The React Server Component Payload is a compact binary representation of the rendered React Server Components tree.

  2. NextJS caching on the Server (Full Route Cache): NextJS by default cache the render result on the server this happen in build time o when tha web revalidate the cache.

  3. React Hydration and Reconciliation on the Client: When client make a request the HTML immediately show a fast non-interactive initial preview, then the React Server Components Payload is used to reconcile the Client and rendered Server Component trees, and update the DOM and finally the JavaScript instructions are used to hydrate Client Components and make the application interactive.

  4. NextJS Caching on the client: The React Server Component Payload is stored in the client-side Router Cache. This is usefull because improve the navigation experience.

  5. Subsequent Navigations: In follow navigations NextJS check if React Server Components Payload is stored in the Router Cache and if yes dont make a requeste to the server.

Router Cache

NextJS store React Server Component Payload in a in-memory client side cache this improve navigation experience for the user because the page don’t make a full-page reload between navigations and the pages have instant backward/forward navigation.

Resources