您好,登錄后才能下訂單哦!
雖然 Vue 的服務器端渲染 (SSR) 相當快速,但是由于需要為每次請求為了避免交叉請求狀態污染,都創建一個新的根Vue實例,創建組件實例和虛擬 DOM 節點的開銷,無法與純基于字符串拼接的模板的性能相當。在 SSR 性能至關重要的情況下,明智地利用緩存策略,可以極大改善響應時間并減少服務器負載。同時還可以大大減少后端接口服務器的負載。
在 vue SSR指南 中,緩存有兩種,分為頁面級緩存和組件級緩存。本次講的是頁面緩存,如果內容不是用戶特定的并且在相對較短時間內,頁面內容不需要更新。我們就可以使用頁面緩存。對于頁面級緩存我們可以通過這段koa服務器的代碼大概知道緩存的思路:
const microCache = LRU({ max: 100, maxAge: 1000 // 重要提示:條目在 1 秒后過期。 }) const isCacheable = req => { // 實現邏輯為,檢查請求是否是用戶特定(user-specific)。 // 只有非用戶特定 (non-user-specific) 頁面才會緩存 } server.get('*', (req, res) => { const cacheable = isCacheable(req) if (cacheable) { const hit = microCache.get(req.url) if (hit) { return res.end(hit) } } renderer.renderToString((err, html) => { res.end(html) if (cacheable) { microCache.set(req.url, html) } }) })
流程圖如下:
上面的代碼為vue的ssr渲染提供了方案,但是對于使用nuxt框架的同學而言,用腳手架初始化完,框架對于vue服務端渲染的res.end()函數做了高度封裝,從下圖nuxt在接收到請求后進行渲染的流程可以看出,nuxt主要是通過nuxtMiddleware調用renderRoute()來進行渲染的:
那么我們是否可以通過重寫renderRoute()這個api攔截其內部渲染邏輯,在渲染之前加上緩存呢? nuxt-ssr-cache 插件已經這樣做了。我們來看一下這個nuxt模塊核心部分的源碼:
const renderer = nuxt.renderer; const renderRoute = renderer.renderRoute.bind(renderer); renderer.renderRoute = function(route, context) { // 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 (!result.error) { cache.setAsync(cacheKey, serialize(result)); } return result; }); } return cache.getAsync(cacheKey) .then(function (cachedResult) { if (cachedResult) { return deserialize(cachedResult); } return renderSetCache(); }) .catch(renderSetCache); };
在這段代碼中,先保存了renderer原來的renderRoute代碼,之后又重寫了renderRoute代碼,返回了一個通過cache緩存來獲取緩存內容的邏輯。cache返回了一個promise,如果是resolve的,并且有緩存的內容,就直接返回緩存內容。如果沒有緩存內容或者reject,就執行renderSetCache()。而renderSetCache()中,返回了原來最初的renderRoute()處理邏輯,同樣如果renderRoute()返回的promise被resolve了,那么就通過cache的setAsync方法來進行緩存,之后返回渲染結果。
使用方法大家自行參考git中的readme文檔,這里就不說了。
下面我們真正來仿真一下,看看這個模塊的功效到底如何。我們通過ab命令
ab -n 4000 -c 50 -s 120 -r http://localhost:3000/
來進行壓測:
第一種情況,沒有添加頁面緩存,大約持續請求了10秒鐘,執行到3600個請求的時候,發生錯誤,不再繼續請求了:
我們來通過日志看下是什么錯誤:
可以看到FATAL ERROR這一句,JavaScript heap out of memory。堆內存已經沒有辦法再進行分配,所以進程終止了。
我們在終止之前通過進程監視器可以看到node進程已經彪到了1.7GB的內存。
第二種情況,我們添加了頁面緩存,通過server端的日志,我們可以看出,只請求了一次后端的api數據接口,說明緩存已經成功攔截了頁面請求。請求數據如下:
在2秒鐘之內,就順利結束了4000個請求,內存沒有任何明顯波動,優化效果顯而易見。
到此這篇關于Nuxt頁面級緩存的實現的文章就介紹到這了,更多相關Nuxt 頁面級緩存內容請搜索億速云以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持億速云!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。