Nextjs 构建应用基础:缓存机制Next可以通过缓存渲染和请求结果来提升性能和渲染开销 Next提供了如下几类缓存机
Next可以通过缓存渲染和请求结果来提升性能和渲染开销
Next提供了如下几类缓存机制:
一、请求记忆
行为
使用fetchAPI
时,在请求URL和参数相同时,Next会将请求结果缓存,即使在组件树的不同位置请求数据,也只会执行一次。这样的好处是不需要在高层级组件获取数据再在子组件中通过props转发数据,而是直接在子组件中请求数据,不会发起多余请求;
原理
如上图,对于路由
/a
,第一次请求会触发cache MISS,执行具体请求, 请求结果会存储到内存中,后续请求会触发cache HIT 直接从内存中获取数据
缓存持续时间
缓存会持续到React组件树渲染完成
无需重新验证
退出方式
const { signal } = new AbortController()
fetch(url, { signal })
二、数据缓存
Next特有的缓存形式,与请求记忆相区别,请求记忆缓存只持续在组件书渲染时, 而数据缓存是持久的。
Next 15 默认不进行数据缓存,需要给fetch方法添加force-cache
参数开启
fetch(`https://...`, { cache: 'force-cache' })
原理
当使用fetchAPI带有force-cache
参数时,会去检查数据缓存中是否有数据, 有则返回,并且请求被记忆。如果没有则发起请求得到数据后存入数据缓存并且记忆。对于没有被缓存的数据,或者配置了no-store
参数,结果总是会从数据缓存中获取并被记忆
缓存持续时间
在传入请求和部署时持续,除非重新验证或者选择退出
重新验证方式
-
基于时间: 配置
next:{revalidate:time}
fetch('https://...', { next: { revalidate: 3600 } })
-
按需重新校验 可以根据路由路径(revalidatePath)和tag(revalidateTag)去重新验证
三、完整路由缓存
在构建过程中自动渲染和缓存路由,这样可以使用被缓存的卤藕而不用在每次请求时重新渲染
过程
Next在渲染过程中会有PSC Payload 和 HTML 产物在服务端这两个会被缓存
在构建时是否会缓存取决于路由类型,静态路由会默认被缓存,动态路由则不会被缓存。
缓存持续时间
缓存是持久的, 并且由于在构建时就被缓存, 可以跨用户请求复用
重新验证方式
- 重新验证数据:重新验证数据缓存会使得组件重新渲染从而使得完整路由缓存失效;
- 重新部署: 完整路由缓存会在重新部署时失效;
退出方式
- 使用动态函数
- 给路由段配置:
dynamic = 'force-dynamic'
,revalidate = 0
- 退出数据缓存:如果路由中有一个请求没有被缓存,则完整路由缓存会被退出
四、路由缓存(客户端缓存)
缓存路由段的RSC Payload。用户在路由间导航时,Next会缓存访问过的路由,并且预取用户可能会访问的路由
过程
当访问路由'/a'
时,cache Miss,页面/a
和布局/layout
放入路由缓存,当访问/b
时, 由于lyaout已经被缓存过,渲染时直接使用先前缓存的layout。缓存页面/b
,当再次访问页面a时,直接使用缓存中的layout和a页面以及b页面。
这样做的好处就是前进和后退导航时,由于对应的路由已经被缓存,布局能够复用,并且页面不会重载
缓存持续时间
- Session: 缓存在导航时持续存在,页面刷新后失效
- 自动失效时间: 默认预取:动态页面不缓存、静态页面会被缓存五分钟 全部预取:动态和静态页面都是五分钟
重新校验
- 在 Server Action 中
通过
revalidatePath
或revalidateTag
重新验证数据 使用cookies.set
或者cookies.delete
方法 - 调用
router.refresh
方法使路由缓存失效并重新获取路由
退出方式
路由缓存无法完全退出,Next 15 版本默认不开启页面组件的路由缓存
五、缓存之间的交互
配置不同缓存机制的情况下,会有一些交互产生:
- 数据缓存和完整路由缓存:
- 重新验证或者退出数据缓存的情况下完整路由缓存会失效
- 完整路由缓存失效的情况下不会影响数据缓存
- 数据缓存和路由缓存
- 可以在Server Action中使用revalidatePath和 revalidateTag使数据缓存和路由缓存立即失效
- 在路由处理程序中重新验证数据缓存不会立即使得路由缓存失效
Next.js中一些API会影响缓存,参考文档
Building Your Application: Caching | Next.js (nextjs.org)
总结
Next.js通过以下缓存机制提升性能:
- 请求记忆:在组件渲染中避免重复请求。
- 数据缓存:跨请求和部署持久保存请求结果。
- 完整路由缓存:构建时预渲染和缓存页面。
- 路由缓存:客户端缓存以快速导航。
这些机制相互配合,可以优化数据加载和页面渲染的效率。
转载自:https://juejin.cn/post/7416275445166096411