Next.js - Request Memoization



Request memoization is a caching technique used to improve performance in Next.js applications. In this chapter, we will learn about request memoization in Next.js, it features, and how to use it to improve performance of applications.

What is Request Memoization?

Request memoization is a caching technique used in web applications to prevent duplicate data fetches during the same render cycle. This is used to improve performance and reduce load times by storing data in server memory or on client browser so that it can be accessed quickly.

How it Works

  • When a fetch request is made, Next.js stores the promise in memory.
  • Subsequent identical requests return the cached promise instead of making new requests.
  • The cache is maintained in each request, meaning it's cleared between different user requests.

Key Facts on Request Memoization

  • Request memoization is a React feature, not a Next.js feature.
  • Memoization only applies to the GET method in fetch requests.
  • Memoization applies to fetch requests in generateMetadata, generateStaticParams, Layouts, Pages, and other Server Components.
  • Memoization doesn't apply to fetch requests in Route Handlers as they are not a part of the React component tree.
  • The memoization cache lasts the lifetime of a server request until the React component tree has finished rendering.

Basic Request Memoization Example

In the following example, we have a React component that fetches user data from an API endpoint. We are calling API endpoint twice, but the fetch request is only made once. The second call uses the cached data from the first call.

"use client";

import { useEffect, useState } from 'react';

function ProductPage() {
  const [data, setData] = useState(null);

  useEffect(() => {
    async function fetchData() {
        const res = await fetch('https://jsonplaceholder.typicode.com/users');
        const result = await res.json();
        setData(result);
    }
    fetchData();
  }, []);

  return (
    <div>
      <h1>User Names</h1>
      {data ? (
        data.map((user) => (
          <div key={user.id} > <p>{user.name}</p> </div>
        ))
      ) : (
        <p>Loading...</p>
      )}
      <h1>User Emails</h1>
      {data ? (
        data.map((user) => (
          <div key={user.id} > <p>{user.email}</p> </div>
        ))
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
}

export default ProductPage;

Output

The output of the above code will display the names and emails of users fetched from the API endpoint. The region highlighted in violet rectangle, show the API call happens in browser dev tools. You can see that, even though we call the API twice, the fetch request is only made once.

Next.js Request Memoization

Advanced Memoization with Parameters

Next.js also allows you to memoize requests with parameters. In the following example, we have a function `getUser()` that fetches user data from an API endpoint. We are calling the function thrice with the same parameter, but the fetch request is only made twice. The second call uses the cached data from the first call.

// app/dashboard/page.tsx
interface User {
    id: string;
    name: string;
    email: string;
}

async function getUser(id: string): Promise<User> {
    const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
    if (!res.ok) throw new Error('Failed to fetch user');

    return res.json();
}

export default async function DashboardPage() {
    console.log('Starting fetches...');

    const startTime = Date.now();

    // These calls will demonstrate memoization
    const user1 = await getUser('1');  // First fetch
    console.log('First user1 fetch completed:', Date.now() - startTime, 'ms');

    const user1Again = await getUser('1');  // Memoized
    console.log('Second user1 fetch completed:', Date.now() - startTime, 'ms');

    const user2 = await getUser('2');  // New fetch
    console.log('User2 fetch completed:', Date.now() - startTime, 'ms');

    return (
        <div>
        <h1>User Dashboard</h1>
        <div>
            <h2>User 1 (First Fetch):</h2>
            <pre>{JSON.stringify(user1, null, 2)}</pre>
            
            <h2>User 1 (Memoized):</h2>
            <pre>{JSON.stringify(user1Again, null, 2)}</pre>
            
            <h2>User 2 (Different Fetch):</h2>
            <pre>{JSON.stringify(user2, null, 2)}</pre>
        </div>
        </div>
    );
}

Output

The output of the above code will display the user data fetched from the API endpoint. You can see that, even though we call the API thrice with the two different parameters, the fetch request is only made twice.

Next.js Parameterized Request Memoization
Advertisements