ThisCalculator

Everyday

Next.js Cache Components: Key Facts on Partial

Updated · Standard formula, shown below

Next.js Cache Components: Key Facts on Partial

Next.js caching can be confusing, especially when you hear about “partial” caching. In short, partial caching in Next.js means that different parts of a page are cached at different levels—some parts are static and cached for a long time, while others are dynamic and fetched on demand. This article explains the key facts you need to know about partial caching in the App Router, how it works, and how to control it.

Background: The Evolution of Next.js Caching

Next.js has evolved from a purely server-rendered framework (Pages Router) to one that offers fine-grained control over rendering and caching (App Router). In the Pages Router, you had getStaticProps for static generation and getServerSideProps for server-side rendering—a binary choice. The App Router introduced a more granular model where you can mix static and dynamic behavior within a single route. This is where “partial” comes in: you can have a page that is mostly static but includes dynamic components that fetch data on each request.

The key shift is that in the App Router, components can be individually marked as static or dynamic, and the cache is applied at the component level, not just the page level. This allows for “partial” caching—some parts of the page are cached, others are not.

How Partial Caching Works in the App Router

In the App Router, every component can be either a Server Component or a Client Component. Server Components can be further classified as static or dynamic based on the APIs they use. The Next.js compiler analyzes each component and decides whether it can be statically rendered (cached) or needs dynamic rendering.

Here’s the breakdown:

  • Static Components: These are rendered at build time or on-demand and cached. They don’t depend on request-time data (like cookies or search params).
  • Dynamic Components: These are rendered on each request because they use request-specific data (like cookies(), headers(), or searchParams).

When a page has a mix of both, Next.js will statically render the static parts and dynamically render the dynamic parts. The static parts are cached, and the dynamic parts are fetched on the fly. This is the essence of partial caching.

For example, consider a product page. The product description (static) can be cached, while the user’s cart count (dynamic) is fetched on each request. Next.js will cache the product description and only re-render the cart count.

Key Facts: What Gets Cached and When

To use partial caching effectively, you need to know what triggers dynamic rendering. Here are the key facts:

  • Dynamic APIs: Using cookies(), headers(), or searchParams in a Server Component makes that component dynamic.
  • fetch requests: By default, fetch requests are cached (unless they use cache: 'no-store'). If a component uses a cached fetch, it can be static. If it uses no-store, it becomes dynamic.
  • Runtime: The runtime setting (e.g., nodejs vs edge) doesn’t directly affect caching, but edge runtime has limitations on some APIs.
  • Dynamic = no cache: When a component is dynamic, it is not cached at all. The entire page is rendered on the server for each request, but only the dynamic parts are re-rendered; the static parts are reused from the cache.

It’s important to note that partial caching is not the same as Incremental Static Regeneration (ISR). ISR caches whole pages and revalidates them at a set interval. Partial caching is more granular—it caches individual components, not necessarily the whole page.

How to Control Partial Caching

You have several ways to control whether a component is static or dynamic:

  • Use dynamic APIs deliberately: If you don’t need request-time data, avoid cookies(), headers(), and searchParams in Server Components.
  • Set fetch options: Use cache: 'force-cache' (default) to cache, or cache: 'no-store' to bypass cache.
  • Use revalidate option: For fetch, you can set next: { revalidate: 60 } to revalidate the cached data every 60 seconds.
  • Use the dynamic route segment config: In a layout.tsx or page.tsx, you can set export const dynamic = 'force-static' or 'force-dynamic' to force the entire route to be static or dynamic.

Here’s a practical example of a component that is dynamic because it uses cookies:

// app/dashboard/page.tsx
import { cookies } from 'next/headers';

export default function Dashboard() {
  const token = cookies().get('token');
  // This component is dynamic because it reads cookies.
  return <div>User token: {token?.value}</div>;
}

If you want to make this static, you’d need to move the cookie reading to a Client Component or pass it as a prop from a parent component that is dynamic.

Common Misconceptions and Pitfalls

One common misconception is that partial caching means the page is partially cached in the browser. Actually, the browser receives the full HTML, but some parts are generated on the server on each request. The caching happens on the server side.

Another pitfall is accidentally making a component dynamic when you don’t need to. For example, using searchParams in a component that doesn’t need it will make the entire page dynamic, defeating the purpose of partial caching. Always check if you really need request-time data.

Also, be aware that using cookies() in a layout will make the layout dynamic, which affects all pages under it. If you only need cookies in a specific page, put the cookie logic in that page, not in the layout.

Comparing Partial Caching to Other Strategies

To understand partial caching, it helps to compare it to other strategies:

  • Full Static: The entire page is cached at build time. Fastest but not suitable for personalized content.
  • Full Dynamic: The entire page is rendered on each request. Slowest but always fresh.
  • ISR: The page is static but revalidated at a fixed interval. Good for content that changes periodically.
  • Partial Caching: The page is a mix of static and dynamic components. Best of both worlds: static parts are fast, dynamic parts are fresh.

Partial caching is ideal for pages that have a mix of global and user-specific content, like a dashboard with a static header and a dynamic user profile.

Performance and Cost Implications

Partial caching can significantly improve performance because static parts are served from the cache, reducing server load. However, it’s not a silver bullet. If you have many dynamic components, the server still has to render them on each request, which can be costly.

From a cost perspective, static rendering is cheaper because it uses less CPU. Dynamic rendering uses more CPU, and if you’re on a serverless platform, you pay per request. Partial caching helps you balance cost and freshness.

To maximize efficiency, aim to make as many components static as possible. Use dynamic components only where necessary. For example, a blog post page can be fully static, but a comment section might be dynamic.

Frequently Asked Questions

Does partial caching work in the Pages Router?

No, partial caching is a feature of the App Router. In the Pages Router, you have to choose between static and dynamic rendering for the whole page. However, you can achieve a similar effect by using client-side data fetching for dynamic parts, but that’s not the same as server-side partial caching.

How do I know if a component is static or dynamic?

You can use the Next.js build output to see which routes are static or dynamic. During next build, it shows a table with the route and its type (Æ’ for dynamic, â—‹ for static). For a more granular view, you can use the next dev mode and inspect the network tab to see if the component is fetched separately.

Can I combine partial caching with ISR?

Yes, you can. For example, you can have a static component that uses fetch with revalidate to update its data periodically (ISR at the component level). This is a powerful pattern for content that changes occasionally.

Does partial caching affect SEO?

No, partial caching does not affect SEO because the HTML is fully rendered on the server. Search engines see the complete page, including the dynamic parts, because they are rendered on the server before being sent to the client.

What happens if I use cookies() in a Client Component?

You can’t use cookies() in a Client Component because it’s a Server Component API. To access cookies on the client, you’d need to read them via document.cookie or pass them as props from a Server Component. If you use document.cookie, the component is still a Client Component, and it doesn’t affect server-side caching.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.