Nuxt组件级缓存

3,334 阅读2分钟

  上一篇讲到了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个请求。

更多精彩文章请关注: