App Router | Caching
Mechanism | What | Where | Purpose | Duration |
---|---|---|---|---|
request-memoization | Return values of functions | Server | Re-use data in a React Component tree | Per-request lifecycle |
data-cache | Data | Server | Store data across user requests and deployments | Persistent (can be revalidated) |
full-route-cache | HTML and RSC payload | Server | Reduce rendering cost and improve performance | Persistent (can be revalidated) |
router-cache | RSC Payload | Client | Reduce server requests on navigation | User session or time-based |
Request Memoization
- 是 react 針對 fetch api 做的擴充
- 是 react feature 不是 next.js 的 feature
- 此功能只做用在 GET method 上 且使用的需要是 fetch api
- 不適用於 route handlers 因為那部分不算 react component tree
- 基本上如果符合上述條件, react 會自動幫忙做 function 層級的 cache,但如果發現沒有被 cache 著,可以使用
React.cache
去達成 cache 的效果 ( 雖然文件說主動會做,但目前看起來沒有,可能是 React 版本不對 ) React.cache
React.use
並尚未正式發佈 文件上還沒有- 發生在 server side 並且區間只在當次 request 當中有作用,所以不用 revalidate
不用在 top-level 就去 request api 做好整理後往下 pass props,藉由 cache 機制也可以在各個 component 當中直接 request 相同的 endpoint,react 會協助 cache,performance 不會因此而受到影響。
import * as React from 'react';
const getUser = React.cache(async function () {
console.log('start', new Date().toISOString());
const resp = await fetch('https://dummyjson.com/users');
console.log('end', new Date().toISOString());
return resp.json();
});
const ServerComponent = async ({ children }: { children: React.ReactNode }) => {
await getUser();
console.log('first time end');
await getUser();
console.log('second time end');
await getUser();
console.log('third time end');
return <div>{children}</div>;
};
export default ServerComponent;