上一篇讲到了nuxt页面缓存,这一篇我们来讲nuxt的组件级缓存。从下图nuxt处理请求的示意图可以看出,在nuxt框架中主要是通过vue-server-renderer这个模块进行渲染的,而vue-server-renderer这个模块自带了组件缓存这一特性。(ssr.vuejs.org/api/#cache)

使用方法就是在createRenderer()执行的时候,配置的对象中加上cache属性:
const LRU = require('lru-cache')
const renderer = createRenderer({
cache: LRU({
max: 10000
})
})
但是nuxt已经将这个方法做了封装,于是我们可以通过nuxt的配置文件nuxt.config.js来配置render属性的bundleRenderer对象,来为vue SSR渲染器定义缓存。
const LRU = require('lru-cache')
module.exports = {
render: {
bundleRenderer: {
cache: LRU({
max: 1000, // 最大的缓存个数
maxAge: 1000 * 60 * 15 // 缓存15分钟
})
}
}
}
我们还可以利用nuxt自带的组件缓存模块component-cache来定义缓存,核心代码很简单,为bundleRenderer定义缓存对象:
this.options.render.bundleRenderer.cache = new LRU(Object.assign({
max: 10000,
maxAge: 1000 * 60 * 15
}, options))
然而只是这样还是不够的,我们还要在待缓存的组件中进行配置:
export default {
name: 'item', // 必填选项
props: ['item'],
serverCacheKey: props => props.item.id,
render (h) {
return h('div', this.item.id)
}
}
要注意两点:
1.name必须唯一。
2.serverCacheKey输入参数为props,如果输入的参数有变,那么一定要体现在serverCacheKey的返回值中。
何时使用组件缓存:
如果 renderer 在组件渲染过程中进行缓存命中,那么它将直接重新使用整个子树的缓存结果。这意味着在以下情况,你不应该缓存组件:
1.它具有可能依赖于全局状态的子组件。
2.它具有对渲染上下文产生副作用(side effect)的子组件。
因此,应该小心使用组件缓存来解决性能瓶颈。在大多数情况下,你不应该也不需要缓存单一实例组件。适用于缓存的最常见类型的组件,是在大的 v-for 列表中重复出现的组件。由于这些组件通常由数据库集合(database collection)中的对象驱动,它们可以使用简单的缓存策略:使用其唯一 id,再加上最后更新的时间戳,来生成其缓存键(cache key):
serverCacheKey: props => props.item.id + '::' + props.item.last_updated
不过对于组件缓存,nuxt进程对于每次请求其实还是要真正到后端请求数据,再和缓存的props进行对比,再决定是否直接使用缓存。而且组件缓存一般作用的组件都是比较简单的列表组件。所以节省的开销不多,用到的时候,优化效果还是要视情况而定。


没有进行组件缓存时,1000个请求,总耗时60秒,平均每秒处理16.45个请求。而缓存后总耗时为51秒,平均每秒处理19.5个请求。
更多精彩文章请关注:
