Teachnique
      CourseRoadmaps
      Login

      Introduction

      Project SetupCLI

      IntroductionAPP RouterTemplateLoading UIError Handling404 Page

      Linking and Navigating

      Dynamic RoutesRoute groupsParallel RoutesIntercepting Routes

      Route handlersCacheCommon Questions

      Middleware

      CSRSSR & SSGISR

      React Server ComponentsServer-Side Rendering

      SuspenseStreaming

      Server & Client ComponentServer vs. Client ComponentBest Practices

      Server-Side Rendering Strategies

      Data Fetching & Caching & RedirectThird-Party Request Libraries on the Server SideBest Practices

      Request MemoizationData CacheFull Route CacheRouter Cache

      Server Actions IFormServer Actions IIOptimistic Update

      Tailwind CSSCSS-in-JSSass

      Environment VariablesAbsolute Imports& Module Path AliasesRoute Segment Config

      Image & LCPImage IImage IIOptimizing IOptimizing II

      Next FontFont ParameterApply Styles

      Feedback

      Submit request if you have any questions.

      Course
      Request Memoization

      Next.js Mastery: From Fundamentals to Full-Stack

      Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.

      Introduction

      In this chapter, we will introduce the caching mechanisms in Next.js.
      The caching feature in Next.js is incredibly powerful, often resulting in a love-hate relationship. On one hand, caching is crucial for optimizing application performance and reducing costs. On the other hand, when working on a Next.js project, you may frequently encounter issues where data does not update, usually because of caching...
      In theory, understanding caching is not essential for using Next.js since it manages caching automatically based on the APIs you use. However, in practice, it's crucial to understand caching to resolve issues effectively when they arise.
      Let's dive into caching now.

      Overview

      Next.js has four types of caching mechanisms:
      Mechanism
      Cached Content
      Storage Location
      Purpose
      Duration
      Request Memoization
      Function return values
      Server
      Reuse data in the React component tree
      Each request's lifecycle
      Data Cache
      Data
      Server
      Reuse data across user requests and deployments
      Persistent (revalidatable)
      Full Route Cache
      HTML and RSC payload
      Server
      Reduce rendering costs and improve performance
      Persistent (revalidatable)
      Router Cache
      RSC payload
      Client
      Reduce server requests during navigation
      User session or time-based
      By default, Next.js uses caching as much as possible to improve performance and reduce costs. For example, routes are statically rendered by default, and the results of data requests are cached. The diagram below shows the process of static route rendering at build time and the first visit to a static route:
      
      In this diagram:
      • During the build time for /a, the requests are made for the first time, resulting in a cache miss. Data is fetched from the data source, stored in request memoization and data cache (SET), and the resulting RSC Payload and HTML are stored in the server's full route cache.
      • When the client visits /a, the cached RSC Payload and HTML are retrieved from the server's cache, and the RSC Payload is also stored in the client's router cache.
      Caching behavior varies depending on several factors, such as whether the route is dynamically or statically rendered, whether the data is cached or uncached, and whether the request is part of the initial access or subsequent navigation.
      Feeling confused? Don't worry. As we progress through the content, you'll gain a deeper understanding.

      Request Memoization

      1. How It Works

      React extends the fetch API to automatically cache the results of requests with the same URL and parameters. This means that even if you request the same data in multiple places in the component tree, the data will only be fetched once.
      
      This allows you to request data directly in the component where it's needed without worrying about the performance impact of making the same request multiple times. You don't need to fetch data at the top level and pass it down via props.
      // app/page.js
      async function getItem() {
      // Automatically cache the result
      const res = await fetch('https://.../item/1');
      return res.json();
      }
      
      // Function called twice, but only one request will be made
      const item = await getItem(); // cache MISS
      
      const item = await getItem(); // cache HIT
      This is the principle behind request memoization:
      
      In this diagram, when rendering the /a route, the first request triggers a cache miss. The function is executed, and the request result is stored in memory (cache SET). On subsequent identical calls, the cached data is retrieved from memory (cache HIT).
      The underlying principle is similar to function memoization. Here's an example from "JavaScript: The Definitive Guide":
      function memoize(f) {
      var cache = {};
      return function() {
      var key = arguments.length + Array.prototype.join.call(arguments, ",");
      if (key in cache) {
      return cache[key];
      } else {
      return cache[key] = f.apply(this, arguments);
      }
      }
      }

      2. Duration

      The cache lasts for the duration of the server request lifecycle until the React component tree has finished rendering. It is intended to prevent multiple requests for the same data during the rendering of the component tree, improving performance.

      3. Revalidation

      Since request memoization is only used during rendering, there is no need for revalidation.

      4. Opting Out

      This behavior is a default optimization in React and is not recommended to opt-out of.
      If you don't want a fetch request to be memoized, you can use the AbortController Web API (although its primary purpose is to abort requests):
      const { signal } = new AbortController();
      fetch(url, { signal });

      5. React Cache

      If you cannot use fetch but still want to implement memoization, you can use React's cache function:
      // utils/get-item.ts
      import { cache } from 'react';
      import db from '@/lib/db';
      
      export const getItem = cache(async (id) => {
      const item = await db.item.findUnique({ id });
      return item;
      });
      Note: To better understand request memoization and data caching, practical examples are provided at the end of this chapter.