Back to blogs

Caching in React and Next js with Best Practices for 2025

May 22, 2025
5 min read
Caching in React and Next js with Best Practices for 2025

In modern web development, speed and efficiency are non-negotiable. Whether you're building with React or leveraging the full power of Next.js, caching has become one of the most crucial techniques for enhancing performance, reducing server load, and improving user experience.


With the latest updates in Next.js and advancements in the React ecosystem, caching strategies have evolved, and mastering them is key for any serious developer. In this blog, we’ll explore how caching works in both React and Next.js, walk through best practices, and highlight real-world examples that you can apply today.


What is Caching?


Caching refers to the process of storing data temporarily so future requests can be served faster. In the context of web applications, caching can occur at various levels:


  1. Browser caching (storing static assets)
  2. Client-side data caching (with libraries like SWR or React Query)
  3. Server-side caching (Next.js API routes or server actions)
  4. CDN caching (via edge networks)


Effective caching minimizes redundant data fetching, accelerates loading times, and improves the perceived performance of your application.


Caching in React Applications


React doesn’t have built-in caching, but the community provides powerful tools to manage cache effectively on the client side.


1. React Query and SWR for Data Caching


These libraries help cache remote data on the client side and reduce unnecessary requests:


import useSWR from 'swr';

const fetcher = (url: string) => fetch(url).then(res => res.json());

export default function User() {
const { data, error } = useSWR('/api/user', fetcher);

if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;
return <div>Hello {data.name}</div>;
}


Best Practices:


  1. Set revalidation intervals (revalidateOnFocus, dedupingInterval)
  2. Use optimistic updates for a snappy UI
  3. Preload data when possible


2. Memoization for Component-Level Caching


For expensive computations and rendering logic:


import { useMemo } from 'react';

const ExpensiveComponent = ({ items }) => {
const sortedItems = useMemo(() => items.sort(), [items]);
return <List items={sortedItems} />;
};


3. LocalStorage and SessionStorage


Persisting client state across sessions:


useEffect(() => {
const cachedData = localStorage.getItem('userData');
if (cachedData) {
setUser(JSON.parse(cachedData));
}
}, []);


Server-Side Caching in Next.js (Latest App Router)


With the App Router in Next.js 13+ and the stability in v14+, server actions and data caching have become much more robust and declarative.


1. Caching with fetch and cache Option


Next.js allows caching behavior to be specified per request:


export async function getProduct(productId: string) {
const res = await fetch(`https://api.example.com/products/${productId}`, {
next: { revalidate: 60 } // ISR (Incremental Static Regeneration)
});
return res.json();
}


Best Practices:


  1. Use cache: 'force-cache' for static content
  2. Use revalidate to regenerate content periodically
  3. Use cache: 'no-store' for dynamic or user-specific data


2. Using Server Actions and React Server Components (RSC)


// app/actions.ts
'use server';

export async function saveData(formData: FormData) {
const name = formData.get('name');
// Save to database or perform API calls
}


Server actions in the App Router allow you to cache server-side logic and fetch results in React Server Components without hydration.


3. Using generateStaticParams and generateMetadata


These methods help Next.js know which routes to pre-build and cache efficiently:


export async function generateStaticParams() {
const products = await fetchProducts();
return products.map(product => ({ id: product.id }));
}


Cache Invalidation Strategies


Proper cache invalidation ensures that stale data is replaced with up-to-date content:


  1. Time-based (revalidate: 60 seconds)
  2. On-demand revalidation (res.revalidate in API route)
  3. Tag-based revalidation (coming soon in Next.js)
  4. Mutations trigger refetch in SWR/React Query


CDN and Edge Caching with Next.js


Vercel and other hosting providers like Netlify and Cloudflare deploy Next.js apps globally. Edge caching improves load time by serving users from the nearest region.


Tips:


  1. Leverage Edge Functions for dynamic personalization
  2. Use headers like Cache-Control effectively
  3. Deploy static assets via CDN for better global performance


Final Best Practices


  1. Prefer static rendering where possible
  2. Cache API calls both on server and client
  3. Use persistent cache (IndexedDB/localStorage) when applicable
  4. Memoize expensive computations
  5. Profile and audit cache hits/misses with dev tools


Conclusion


Caching in React and Next.js is no longer optional—it’s essential for delivering fast, resilient, and scalable applications. Whether you're fetching data client-side or leveraging powerful server-side features in Next.js App Router, the right caching strategy can drastically improve your app’s performance and user satisfaction. As frameworks evolve, staying updated with caching best practices ensures your apps remain performant and competitive.

By applying these techniques, you not only enhance the speed and reliability of your applications but also reduce infrastructure costs and improve SEO outcomes. Start caching smartly today and take your web performance to the next level.

caching in reactcaching in next jsreact performance optimizationnext js caching strategiesreact best practicesserver-side caching in next jsclient-side caching in reactnext js static generationreact app optimizationincremental static regeneration next jsnext js data fetchingapi caching in reactoptimize react componentscaching strategies for next jsimprove performance in react apps