国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

nuxt.js 緩存實(shí)踐

2019-11-19 13:36:29
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

nuxt 是基于 vue 的 ssr 解決方案,可以是使用vue語(yǔ)法完成前后端的同構(gòu)。

然而在與傳統(tǒng)純字符串拼接的 ssr 方案相比,性能就沒那么好了, nuxt 需要在服務(wù)端生成虛擬 dom ,然后再序列化出HTML字符串,我們常說(shuō) nodejs 的高性能指的是異步IO操作頻繁的場(chǎng)景而非CPU操作密集的場(chǎng)景,畢竟 nodejs 是運(yùn)行在單線程下的,在涉及到高并發(fā)的場(chǎng)景下,性能就會(huì)有所下降,可以考慮采用合理的緩存策略

nuxt 的緩存可以分為 組件級(jí)別緩存 , API級(jí)別緩存 以及 頁(yè)面級(jí)別緩存

組件級(jí)別的緩存

配置項(xiàng) nuxt.config.js 的配置大概長(zhǎng)這樣子:

const LRU = require('lru-cache')module.exports = { render: {  bundleRenderer: {   cache: LRU({    max: 1000,           // 最大的緩存?zhèn)€數(shù)    maxAge: 1000 * 60 * 15    // 緩存15分鐘   })  } }}

并不是說(shuō)配了該項(xiàng)就實(shí)現(xiàn)了組件級(jí)別的緩存,還需要在需做緩存的 vue 組件上增加 name 以及 serverCacheKey 字段,以確定緩存的唯一鍵值,比如:

export default { name: 'AppHeader', props: ['type'], serverCacheKey: props => props.type}

上述組件會(huì)根據(jù)父組件傳下來(lái)的 type 值去做緩存,鍵值是: AppHeader::${props.type} ,由此,新的請(qǐng)求到來(lái)時(shí),只要父組件傳下來(lái)的 type 屬性之前處理過(guò),就可以復(fù)用之前的渲染緩存結(jié)果,以增進(jìn)性能

從該例子可以看出,如果該組件除了依賴父組件的 type 屬性,還依賴于別的屬性, serverCacheKey 這里也要做出相應(yīng)的改變,因此,如果組件依賴于很多的全局狀態(tài),或者,依賴的狀態(tài)取值非常多,意味需要緩存會(huì)被頻繁被設(shè)置而導(dǎo)致溢出,其實(shí)就沒有多大意義了,在 lru-cache 的配置中,設(shè)置的最大緩存?zhèn)€數(shù)是1000,超出部分就會(huì)被清掉

其次,不應(yīng)該緩存可能對(duì)渲染上下文產(chǎn)生副作用的子組件,比如,組件的 created beforeCreated 的鉤子在服務(wù)端也會(huì)走,組件被緩存后就不會(huì)執(zhí)行了,這些可能影響到渲染上下文的地方也要小心,更多內(nèi)容請(qǐng)參考:組件級(jí)別緩存

一般來(lái)說(shuō),比較適合的場(chǎng)景是 v-for 大量數(shù)據(jù)的渲染,因?yàn)檠h(huán)操作比較耗cpu

API級(jí)別的緩存

在服務(wù)端渲染的場(chǎng)景中,往往會(huì)將請(qǐng)求放在服務(wù)端去做,渲染完頁(yè)面再返回給瀏覽器,而有些接口是可以去做緩存的,比如,不依賴登錄態(tài)且不依賴過(guò)多參數(shù)的接口或者是單純獲取配置數(shù)據(jù)的接口等,接口的處理也是需要時(shí)間的,對(duì)接口的緩存可以加快每個(gè)請(qǐng)求的處理速度,更快地釋放掉請(qǐng)求,從而增進(jìn)性能

api的請(qǐng)求使用 axios , axios 即可以在服務(wù)端使用也可是在瀏覽器使用,代碼大概長(zhǎng)這樣子

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 // 服務(wù)端才加緩存,瀏覽器端就不管了 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) {    // 返回結(jié)果前先設(shè)置緩存    CACHED.set(key, rsp.data)   }   return rsp.data  })}

使用上跟平時(shí)使用 axios 還是一樣的,就多加了個(gè) cache 的屬性標(biāo)識(shí)是否需要在服務(wù)端做緩存

const api = { getGames: params => request({  url: '/gameInfo/gatGames',  params,  cache: true })}

頁(yè)面級(jí)別的緩存

在不依賴于登錄態(tài)以及過(guò)多參數(shù)的情況下,如果并發(fā)量很大,可以考慮使用頁(yè)面級(jí)別的緩存, 在 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  }) ]}

上面的例子根據(jù)鏈接后面的參數(shù) pageType 去做緩存,如果鏈接后面有 pageType 參數(shù),就做緩存,緩存時(shí)間為1秒,也就是說(shuō)在1秒內(nèi)相同的 pageType 請(qǐng)求,服務(wù)端只會(huì)執(zhí)行一次完整的渲染

nuxt-page-cache 參考了route-cache ,寫得比較簡(jiǎn)陋,你也可以重新封裝下,nuxt最終返回?cái)?shù)據(jù)是使用 res.end(html, 'utf-8') ,頁(yè)面級(jí)別的緩存大概的思想如下:

const LRU = require('lru-cache')let cacheStore = new LRU({ max: 100,     // 設(shè)置最大的緩存?zhèn)€數(shù) maxAge: 200})module.exports.cacheSeconds = function (secondsTTL, cacheKey) { // 設(shè)置緩存的時(shí)間 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調(diào)用res.end實(shí)際上是調(diào)用該方法,  res.end = function () {   if (res.statusCode === 200) {    // 設(shè)置緩存    cacheStore.set(key, data, ttl)   }   // 最終返回結(jié)果   res.original_end(data, 'utf-8')  } }}

如果緩存命中,直接將原先的計(jì)算結(jié)果返回,大大提供了性能

總結(jié)

在高并發(fā)的情況下可以考慮使用緩存,而緩存策略的使用需要視場(chǎng)景而定,這里不再贅述,還可以考慮使用pm2開啟集群模式去管理我們的進(jìn)程,從而滿足更高的并發(fā)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 玉田县| 塔城市| 南漳县| 周口市| 花莲市| 札达县| 内黄县| 沂南县| 江达县| 安溪县| 丰顺县| 翁牛特旗| 海宁市| 淅川县| 崇州市| 四子王旗| 抚宁县| 呼图壁县| 鹤峰县| 龙泉市| 仪征市| 岳池县| 庐江县| 甘洛县| 安义县| 楚雄市| 康平县| 成武县| 霍林郭勒市| 永吉县| 龙川县| 利辛县| 定州市| 塘沽区| 德令哈市| 南投县| 安乡县| 吐鲁番市| 舞钢市| 射洪县| 孟州市|