面试题答案
一键面试Next.js 本身提供的缓存机制
-
In-memory cache
- Next.js caches the results of
getServerSideProps
in memory on the server. If the same page is requested again within a short time, and the cache is still valid, the cached data will be used instead of re - runninggetServerSideProps
. This is a built - in performance optimization. For example, if you have a blog page that fetches the latest blog posts usinggetServerSideProps
, and multiple requests come in quickly, the first request will execute the data - fetching logic, and subsequent requests will use the cached result.
- Next.js caches the results of
-
Stale - while - Revalidate
- Next.js supports the Stale - while - Revalidate pattern. You can set a
maxAge
andstaleWhileRevalidate
option in thegetServerSideProps
context. maxAge
: This determines how long the cached data is considered fresh. For instance, if you setmaxAge: 60
, the cached data is fresh for 60 seconds. After this time, the data is considered stale.staleWhileRevalidate
: This specifies how long the server can serve stale data while re - validating it in the background. For example, if you setmaxAge: 60
andstaleWhileRevalidate: 300
, for the first 60 seconds, the fresh cached data is served. After 60 seconds, the stale data is served for up to 300 seconds while the server re - runsgetServerSideProps
to get fresh data. When the new data is available, it replaces the stale data in the cache.
export async function getServerSideProps(context) { const res = await fetch('https://example.com/api/data'); const data = await res.json(); return { props: { data }, revalidate: 60 // equivalent to maxAge in this case, and staleWhileRevalidate is not set explicitly here, but can be }; }
- Next.js supports the Stale - while - Revalidate pattern. You can set a
Custom optimization strategies
- External caching
- Using Redis:
- Install the
ioredis
orredis - node
library in your Next.js project. - In your
getServerSideProps
, before making the actual data - fetching call (e.g., to an API), check if the data is already in the Redis cache. If it is, return the cached data. If not, make the API call, store the result in Redis, and then return the data.
import Redis from 'ioredis'; const redis = new Redis(); export async function getServerSideProps(context) { const cachedData = await redis.get('my - data - key'); if (cachedData) { return { props: { data: JSON.parse(cachedData) } }; } const res = await fetch('https://example.com/api/data'); const data = await res.json(); await redis.set('my - data - key', JSON.stringify(data)); return { props: { data } }; }
- Install the
- Using Redis:
- Cache - busting based on data changes
- If your data has some kind of versioning or change - tracking mechanism (e.g., a database has a
last_updated
timestamp), you can incorporate this into your caching strategy. - In
getServerSideProps
, when checking the cache, also check if the version of the data in the cache is up - to - date. If not, re - fetch the data. For example, if your API returns thelast_updated
timestamp along with the data:
export async function getServerSideProps(context) { const cachedData = await redis.get('my - data - key'); if (cachedData) { const { data, last_updated } = JSON.parse(cachedData); const res = await fetch('https://example.com/api/data - version'); const currentVersion = await res.json(); if (currentVersion.last_updated === last_updated) { return { props: { data } }; } } const res = await fetch('https://example.com/api/data'); const data = await res.json(); await redis.set('my - data - key', JSON.stringify(data)); return { props: { data } }; }
- If your data has some kind of versioning or change - tracking mechanism (e.g., a database has a
- Conditional caching
- You can cache data conditionally based on user - specific or request - specific factors. For example, if your page has different data based on the user's locale, you can create cache keys that include the locale information.
export async function getServerSideProps(context) { const locale = context.locale; const cacheKey = `my - data - ${locale}`; const cachedData = await redis.get(cacheKey); if (cachedData) { return { props: { data: JSON.parse(cachedData) } }; } const res = await fetch(`https://example.com/api/data?locale=${locale}`); const data = await res.json(); await redis.set(cacheKey, JSON.stringify(data)); return { props: { data } }; }