您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關nuxt.js中緩存的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
nuxt 是基于 vue 的 ssr 解決方案,可以是使用vue語法完成前后端的同構。
然而在與傳統純字符串拼接的 ssr 方案相比,性能就沒那么好了, nuxt 需要在服務端生成虛擬 dom ,然后再序列化出HTML字符串,我們常說 nodejs 的高性能指的是異步IO操作頻繁的場景而非CPU操作密集的場景,畢竟 nodejs 是運行在單線程下的,在涉及到高并發的場景下,性能就會有所下降,可以考慮采用合理的緩存策略
nuxt 的緩存可以分為 組件級別緩存 , API級別緩存 以及 頁面級別緩存
組件級別的緩存
配置項 nuxt.config.js
的配置大概長這樣子:
const LRU = require('lru-cache') module.exports = { render: { bundleRenderer: { cache: LRU({ max: 1000, // 最大的緩存個數 maxAge: 1000 * 60 * 15 // 緩存15分鐘 }) } } }
并不是說配了該項就實現了組件級別的緩存,還需要在需做緩存的 vue 組件上增加 name
以及 serverCacheKey
字段,以確定緩存的唯一鍵值,比如:
export default { name: 'AppHeader', props: ['type'], serverCacheKey: props => props.type }
上述組件會根據父組件傳下來的 type 值去做緩存,鍵值是: AppHeader::${props.type}
,由此,新的請求到來時,只要父組件傳下來的 type 屬性之前處理過,就可以復用之前的渲染緩存結果,以增進性能
從該例子可以看出,如果該組件除了依賴父組件的 type
屬性,還依賴于別的屬性, serverCacheKey
這里也要做出相應的改變,因此,如果組件依賴于很多的全局狀態,或者,依賴的狀態取值非常多,意味需要緩存會被頻繁被設置而導致溢出,其實就沒有多大意義了,在 lru-cache
的配置中,設置的最大緩存個數是1000,超出部分就會被清掉
其次,不應該緩存可能對渲染上下文產生副作用的子組件,比如,組件的 created
與 beforeCreated
的鉤子在服務端也會走,組件被緩存后就不會執行了,這些可能影響到渲染上下文的地方也要小心,更多內容請參考:組件級別緩存
一般來說,比較適合的場景是 v-for 大量數據的渲染,因為循環操作比較耗cpu
API級別的緩存
在服務端渲染的場景中,往往會將請求放在服務端去做,渲染完頁面再返回給瀏覽器,而有些接口是可以去做緩存的,比如,不依賴登錄態且不依賴過多參數的接口或者是單純獲取配置數據的接口等,接口的處理也是需要時間的,對接口的緩存可以加快每個請求的處理速度,更快地釋放掉請求,從而增進性能
api的請求使用 axios , axios 即可以在服務端使用也可是在瀏覽器使用,代碼大概長這樣子
import axios from 'axios' import md5 from 'md5' import LRU from 'lru-cache' // 給api加3秒緩存 const CACHED = LRU({ max: 1000, maxAge: 1000 * 3 }) function request (config) { let key // 服務端才加緩存,瀏覽器端就不管了 if (config.cache && !process.browser) { const { params = {}, data = {} } = config key = md5(config.url + JSON.stringify(params) + JSON.stringify(data)) if (CACHED.has(key)) { // 緩存命中 return Promise.resolve(CACHED.get(key)) } } return axios(config) .then(rsp => { if (config.cache && !process.browser) { // 返回結果前先設置緩存 CACHED.set(key, rsp.data) } return rsp.data }) }
使用上跟平時使用 axios 還是一樣的,就多加了個 cache 的屬性標識是否需要在服務端做緩存
const api = { getGames: params => request({ url: '/gameInfo/gatGames', params, cache: true }) }
頁面級別的緩存
在不依賴于登錄態以及過多參數的情況下,如果并發量很大,可以考慮使用頁面級別的緩存, 在 nuxt.config.js
增加 serverMiddleware
屬性
const nuxtPageCache = require('nuxt-page-cache') module.exports = { serverMiddleware: [ nuxtPageCache.cacheSeconds(1, req => { if (req.query && req.query.pageType) { return req.query.pageType } return false }) ] }
上面的例子根據鏈接后面的參數 pageType 去做緩存,如果鏈接后面有 pageType 參數,就做緩存,緩存時間為1秒,也就是說在1秒內相同的 pageType 請求,服務端只會執行一次完整的渲染
nuxt-page-cache 參考了route-cache ,寫得比較簡陋,你也可以重新封裝下,nuxt最終返回數據是使用 res.end(html, 'utf-8') ,頁面級別的緩存大概的思想如下:
const LRU = require('lru-cache') let cacheStore = new LRU({ max: 100, // 設置最大的緩存個數 maxAge: 200 }) module.exports.cacheSeconds = function (secondsTTL, cacheKey) { // 設置緩存的時間 const ttl = secondsTTL * 1000 return function (req, res, next) { // 獲取緩存的key值 let key = req.originalUrl if (typeof cacheKey === 'function') { key = cacheKey(req, res) if (!key) { return next() } } else if (typeof cacheKey === 'string') { key = cacheKey } // 如果緩存命中,直接返回 const value = cacheStore.get(key) if (value) { return res.end(value, 'utf-8') } // 緩存原先的end方案 res.original_end = res.end // 重寫res.end方案,由此nuxt調用res.end實際上是調用該方法, res.end = function () { if (res.statusCode === 200) { // 設置緩存 cacheStore.set(key, data, ttl) } // 最終返回結果 res.original_end(data, 'utf-8') } } }
如果緩存命中,直接將原先的計算結果返回,大大提供了性能
感謝各位的閱讀!關于“nuxt.js中緩存的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。