Nuxt页⾯级缓存的实现
cacheable虽然 Vue 的服务器端渲染 (SSR) 相当快速,但是由于需要为每次请求为了避免交叉请求状态污染,都创建⼀个新的根Vue实例,创建组件实例和虚拟 DOM 节点的开销,⽆法与纯基于字符串拼接的模板的性能相当。在 SSR 性能⾄关重要的情况下,明智地利⽤缓存策略,可以极⼤改善响应时间并减少服务器负载。同时还可以⼤⼤减少后端接⼝服务器的负载。
在中,缓存有两种,分为页⾯级缓存和组件级缓存。本次讲的是页⾯缓存,如果内容不是⽤户特定的并且在相对较短时间内,页⾯内容不需要更新。我们就可以使⽤页⾯缓存。对于页⾯级缓存我们可以通过这段koa服务器的代码⼤概知道缓存的思路:
const microCache = LRU({
max: 100,
maxAge: 1000 // 重要提⽰:条⽬在 1 秒后过期。
})
const isCacheable = req => {
// 实现逻辑为,检查请求是否是⽤户特定(user-specific)。
// 只有⾮⽤户特定 (non-user-specific) 页⾯才会缓存
}
<('*', (req, res) => {
const cacheable = isCacheable(req)
if (cacheable) {
const hit = (req.url)
if (hit) {
d(hit)
}
}
if (cacheable) {
microCache.set(req.url, html)
}
})
})
流程图如下:
上⾯的代码为vue的ssr渲染提供了⽅案,但是对于使⽤nuxt框架的同学⽽⾔,⽤脚⼿架初始化完,框架对于vue服务端渲染的d()函数做了⾼度封装,从下图nuxt在接收到请求后进⾏渲染的流程可以看出,nuxt主要是通过nuxtMiddleware调⽤renderRoute()来进⾏渲染的:
那么我们是否可以通过重写renderRoute()这个api拦截其内部渲染逻辑,在渲染之前加上缓存呢?插件已经这样做了。我们来看⼀下这个nuxt模块核⼼部分的源码:
const renderer = derer;
const renderRoute = derRoute.bind(renderer);
// hopefully cache reset is finished up to this point.
tryStoreVersion(cache, currentVersion);
const cacheKey = (config.cache.key || defaultCacheKeyBuilder)(route, context);
if (!cacheKey) return renderRoute(route, context);
function renderSetCache(){
return renderRoute(route, context)
.then(function(result) {
if (!) {
cache.setAsync(cacheKey, serialize(result));
}
return result;
});
}
Async(cacheKey)
.then(function (cachedResult) {
if (cachedResult) {
return deserialize(cachedResult);
}
return renderSetCache();
})
.catch(renderSetCache);
};
在这段代码中,先保存了renderer原来的renderRoute代码,之后⼜重写了renderRoute代码,返回了⼀个通过cache缓存来获取缓存内容的逻辑。cache返回了⼀个promise,如果是resolve的,并且有缓存的内容,就直接返回缓存内容。如果没有缓存内容或者reject,就执⾏renderSetCache()。⽽renderSetCa
che()中,返回了原来最初的renderRoute()处理逻辑,同样如果renderRoute()返回的promise被resolve了,那么就通过cache的setAsync⽅法来进⾏缓存,之后返回渲染结果。
使⽤⽅法⼤家⾃⾏参考git中的readme⽂档,这⾥就不说了。
下⾯我们真正来仿真⼀下,看看这个模块的功效到底如何。我们通过ab命令
ab -n 4000 -c 50 -s 120 -r localhost:3000/
来进⾏压测:
第⼀种情况,没有添加页⾯缓存,⼤约持续请求了10秒钟,执⾏到3600个请求的时候,发⽣错误,不再继续请求了:
我们来通过⽇志看下是什么错误:
可以看到FATAL ERROR这⼀句,JavaScript heap out of memory。堆内存已经没有办法再进⾏分配,所以进程终⽌了。
我们在终⽌之前通过进程监视器可以看到node进程已经彪到了1.7GB的内存。
第⼆种情况,我们添加了页⾯缓存,通过server端的⽇志,我们可以看出,只请求了⼀次后端的api数据接⼝,说明缓存已经成功拦截了页⾯请求。请求数据如下:
在2秒钟之内,就顺利结束了4000个请求,内存没有任何明显波动,优化效果显⽽易见。
到此这篇关于Nuxt页⾯级缓存的实现的⽂章就介绍到这了,更多相关Nuxt 页⾯级缓存内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论