欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Nuxt.js項(xiàng)目的服務(wù)端性能優(yōu)化與錯(cuò)誤檢測(cè)(容錯(cuò)處理)

 更新時(shí)間:2019年10月23日 08:30:57   作者:君華  
這篇文章主要介紹了基于Nuxt.js項(xiàng)目的服務(wù)端性能優(yōu)化與錯(cuò)誤檢測(cè)(容錯(cuò)處理),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

nuxt.js 是一個(gè)基于 Vue.js 的服務(wù)端渲染應(yīng)用框架,使用nuxt.js在做同構(gòu)項(xiàng)目開(kāi)發(fā)時(shí),需要考慮的一些點(diǎn)總結(jié)如下:

一、node服務(wù)端性能優(yōu)化(提高node應(yīng)用程序處理高流量的能力)

基于nuxt.js的服務(wù)端渲染項(xiàng)目我們能做的服務(wù)端性能優(yōu)化有以下幾點(diǎn)(需要注意的是持久化緩存不應(yīng)該在本地開(kāi)發(fā)環(huán)境去做,這樣在緩存期間不會(huì)暴露本地開(kāi)發(fā)中代碼的問(wèn)題)

優(yōu)化點(diǎn) 參考文檔及思路 優(yōu)化場(chǎng)景/條件 特別說(shuō)明 檢測(cè)方法
1. 頁(yè)面緩存 vue官方文檔 頁(yè)面內(nèi)容不是用戶特定(即對(duì)于相同的 URL,總是為所有用戶渲染相同的內(nèi)容) 一般來(lái)說(shuō),一個(gè)頁(yè)面在服務(wù)端做了持久化緩存,那么對(duì)應(yīng)頁(yè)面的存在的api緩存,組件緩存也就沒(méi)有意義了,對(duì)于頁(yè)面緩存與api緩存同時(shí)存在的情況下(有可能存在),api緩存的時(shí)間應(yīng)該比頁(yè)面緩存的時(shí)間小,這樣是為了讓api響應(yīng)的內(nèi)容保持最新 1、代碼本地測(cè)試:在asyncData中打印測(cè)試日志,頁(yè)面緩存后,刷新頁(yè)面后服務(wù)端不會(huì)輸出測(cè)試日志;2、比較html頁(yè)面加載的DOMContentLoaded時(shí)間,刷新頁(yè)面可以看到緩存后的值比首次頁(yè)面加載(未緩存)的值要小
2. api緩存 在axios請(qǐng)求與響應(yīng)攔截器中去做 接口響應(yīng)內(nèi)容不是用戶特定(即對(duì)于相同的api接口URL,即總是為所有用戶響應(yīng)相同的內(nèi)容) 一般請(qǐng)求方式為GET的api請(qǐng)求 比較首次請(qǐng)求與緩存后的api接口響應(yīng)的時(shí)間
3. 組件緩存 nuxtjs官網(wǎng)文檔 vue 官網(wǎng)文檔 不依賴與全局狀態(tài),對(duì)渲染上下文不產(chǎn)生副作用的子組件 要緩存的組件name值必須唯一,serverCacheKey根據(jù)某個(gè)prop的值作為唯一key 檢測(cè)方法同頁(yè)面緩存檢測(cè)方法一致,這個(gè)可能幾乎察覺(jué)不到
4. asyncData函數(shù)優(yōu)化 Promise.all 該函數(shù)中請(qǐng)求api接口數(shù)超過(guò)1個(gè),多的甚至達(dá)到10,20多個(gè),這種情況我們不能使用async await,請(qǐng)求完一個(gè)再接著請(qǐng)求下一個(gè)(同步請(qǐng)求接口);如果有10個(gè)接口需要請(qǐng)求,每個(gè)接口平均響應(yīng)1s,那么至少需要10s才會(huì)響應(yīng)html頁(yè)面;如果使用Promise.all異步請(qǐng)求10個(gè)接口,那么最快接近1s響應(yīng)html頁(yè)面; asyncData函數(shù)會(huì)在服務(wù)端執(zhí)行代碼,因此一定要做好容錯(cuò)處理;另外如果該函數(shù)代碼一直未執(zhí)行完,那么頁(yè)面首次響應(yīng)將會(huì)被掛起,一直處于加載中 對(duì)于頁(yè)面首次加載,該函數(shù)執(zhí)行耗時(shí)越短,頁(yè)面響應(yīng)時(shí)間就越短(頁(yè)面加載越快)

1、頁(yè)面緩存功能模塊實(shí)現(xiàn)

我們?cè)陧?xiàng)目根目錄中創(chuàng)建一個(gè)文件 ~/serverMiddleware/page-cache.js

import LRUCache from 'lru-cache'

const cache = new LRUCache({
 maxAge: 1000 * 60 * 2, // 有效期2分鐘
 max: 1000 // 最大緩存數(shù)量
})

export default function(req, res, next) {
 // 本地開(kāi)發(fā)環(huán)境不做頁(yè)面緩存
 if (process.env.NODE_ENV !== 'development') {
 try {
  const cacheKey = req.url
  const cacheData = cache.get(cacheKey)
  if (cacheData) {
  return res.end(cacheData, 'utf8')
  }
  const originalEnd = res.end
  res.end = function(data) {
  cache.set(cacheKey, data)
  originalEnd.call(res, ...arguments)
  }
 } catch(error) {
  // console.log(`page-cache-middleware: ${error}`)
  next()
 }
 }
 next()
}

2、api緩存功能模塊實(shí)現(xiàn)

我們?cè)陧?xiàng)目根目錄中分別創(chuàng)建兩個(gè)文件 ~/plugins/axios/createCacheKey.js 與 ~/plugins/axios/cache.js ;特別坑的一點(diǎn)是nuxt.js開(kāi)發(fā)環(huán)境cache.js插件代碼在頁(yè)面刷新,路由切換都相當(dāng)于首次運(yùn)行,因此你會(huì)發(fā)現(xiàn)緩存功能失效,只有在 process.env.NODE_ENV === 'production' 生產(chǎn)環(huán)境中測(cè)試有效

// ~/plugins/axios/createCacheKey.js

import md5 from 'md5'

/**
 * 根據(jù)請(qǐng)求配置,是否是請(qǐng)求攔截器 創(chuàng)建緩存key
 * @param {Object} config
 * @param {Boolean} isRequest 
 */

export default function createCacheKey(
 config = {},
 isRequest = false
) {
 const {
 url,
 data,
 params,
 method,
 baseURL,
 } = config || {}

 let commonUrl = url

 /**
 * request攔截器中config.url是未拼接baseURL的,response攔截器中response.config.url是拼接過(guò)baseURL的,
 * 為了保持統(tǒng)一,使用統(tǒng)一拼接baseURL的commonUrl;注意下面的if條件判斷
 */
 if (isRequest && !commonUrl.match(baseURL) && !commonUrl.match(/^https?/)) {
 commonUrl = !!baseURL.match(/.+\/$/) ? `${baseURL.replace(/\/$/, '')}${url}` : `${baseURL}${url}`
 }

 // 根據(jù)請(qǐng)求指令,url,body體,參數(shù)生成規(guī)則
 const rule = `method=${method}-url=${commonUrl}-data=${JSON.stringify(data || {})}-params=${JSON.stringify(params || {})}`

 // md5加密
 return md5(rule)
}

// ~/plugins/axios/cache.js

import LRUCache from 'lru-cache'
import axios from 'axios'
import globalConfig from '../../global-config'
import createCacheKey from './createCacheKey'

const cache = new LRUCache({
 maxAge: 1000 * 60, // 有效期60秒,如果存在頁(yè)面緩存,api緩存的時(shí)間應(yīng)該比頁(yè)面緩存的時(shí)間小,這樣是為了讓api響應(yīng)的內(nèi)容保持最新
 max: 1000 // 最大緩存數(shù)量
})

/**
 * matchCacheCondition 是否滿足持久化緩存條件:服務(wù)端運(yùn)行時(shí) && 非本地開(kāi)發(fā)環(huán)境 && api請(qǐng)求為get請(qǐng)求方式
 * @param {Object} config 請(qǐng)求配置
 */
function matchCacheCondition(config = {}) {
 return process.server && process.env.NODE_ENV !== 'development' && config.method.toLowerCase() === 'get'
}

/**
 * 如果所有頁(yè)面都啟用了緩存,api緩存就沒(méi)有必要了
 */
export default function({ $axios, redirect }) {
 $axios.interceptors.request.use(config => {
 const { baseUrl } = globalConfig
 config.baseURL = baseUrl[process.env.environment] || baseUrl['other']

 // 不滿足緩存條件直接return config
 if (!matchCacheCondition(config)) {
  return config
 }

 const cacheKey = createCacheKey(config, true)
 const cacheData = cache.get(cacheKey)

 if (cacheData) {
  const source = axios.CancelToken.source()
  config.cancelToken = source.token
  source.cancel({ cacheData, cacheKey, url: config.url })
  return config
 }

 return config
 })

 $axios.interceptors.response.use(response => {
 if (matchCacheCondition(response.config)) {
  cache.set(createCacheKey(response.config), response)
 }
 return response
 }, (error) => {
 if (axios.isCancel(error) && matchCacheCondition(response.config)) {
  // console.log(`當(dāng)前頁(yè)面組件asyncData或者fetch函數(shù)中被緩存的接口url為:${error.message.url}`)
  return Promise.resolve(error.message.cacheData)
 }

 // 服務(wù)端打印api接口請(qǐng)求錯(cuò)誤日志
 if (process.server) {
  try {
  const {
   config: {
   url
   },
   message
  } = error || {}
  console.log(`請(qǐng)求url:${url},錯(cuò)誤消息:${message}`)
  } catch(error) {
  // console.log(error)
  }
 }

 // 服務(wù)端,客戶端統(tǒng)一reject錯(cuò)誤對(duì)象,因此頁(yè)面組件asyncData,fetch函數(shù)請(qǐng)求api接口一定要做catch處理
 return Promise.reject(error)
 })
}

3、組件緩存

vue官網(wǎng)文檔原話:如果 renderer 在組件渲染過(guò)程中進(jìn)行緩存命中,那么它將直接重新使用整個(gè)子樹(shù)的緩存結(jié)果。這意味著在以下情況,你不應(yīng)該緩存組件:

  • 它具有可能依賴于全局狀態(tài)的子組件。
  • 它具有對(duì)渲染上下文產(chǎn)生副作用(side effect)的子組件。

因此,應(yīng)該小心使用組件緩存來(lái)解決性能瓶頸。在大多數(shù)情況下,你不應(yīng)該也不需要緩存單一實(shí)例組件。適用于緩存的最常見(jiàn)類型的組件,是在大的 v-for 列表中重復(fù)出現(xiàn)的組件。由于這些組件通常由數(shù)據(jù)庫(kù)集合(database collection)中的對(duì)象驅(qū)動(dòng),它們可以使用簡(jiǎn)單的緩存策略:使用其唯一 id,再加上最后更新的時(shí)間戳,來(lái)生成其緩存鍵(cache key):

serverCacheKey: props => props.item.id + '::' + props.item.last_updated

4、頁(yè)面組件asyncData函數(shù)優(yōu)化

舉一個(gè)簡(jiǎn)單的例子進(jìn)行優(yōu)化

{
 async asyncData({ $axios }) {
 // 1、增加catch處理,是為了讓服務(wù)端,客戶端運(yùn)行時(shí)不報(bào)錯(cuò),特別是防止服務(wù)端運(yùn)行時(shí)不報(bào)錯(cuò),不然頁(yè)面就掛了
 // 2、catch函數(shù)返回一個(gè)resolve空字面量對(duì)象的Promise,表明dataPromise1的狀態(tài)未來(lái)始終是resolved狀態(tài)
 const dataPromise1 = $axios.get('/api/data1').catch(() => Promise.resolve({}))

 const dataPromise2 = $axios.get('/api/data2').catch(() => Promise.resolve({}))
 const dataPromise3 = $axios.get('/api/data3').catch(() => Promise.resolve({}))
 const dataPromise4 = $axios.get('/api/data4').catch(() => Promise.resolve({}))
 const dataPromise5 = $axios.get('/api/data5').catch(() => Promise.resolve({}))
 const dataPromise6 = $axios.get('/api/data6').catch(() => Promise.resolve({}))
 const dataPromise7 = $axios.get('/api/data7').catch(() => Promise.resolve({}))
 const dataPromise8 = $axios.get('/api/data8').catch(() => Promise.resolve({}))

 // 保證apiData有數(shù)據(jù)
 const apiData = await new Promise(resolve => {
  Promise.all([
  dataPromise1, dataPromise2, dataPromise3, dataPromise4,
  dataPromise5, dataPromise6, dataPromise7, dataPromise8,
  ])
  .then(dataGather => {
   resolve({
   data1: dataGather[0],
   data2: dataGather[1],
   data3: dataGather[2],
   data4: dataGather[3],
   data5: dataGather[4],
   data6: dataGather[5],
   data7: dataGather[6],
   data8: dataGather[7],
   })
  })
 })

 return apiData
 }
}

二、node服務(wù)端錯(cuò)誤檢測(cè),容錯(cuò)處理(提高node應(yīng)用程序處理容錯(cuò)的能力)

首先確定使用nuxt.js框架,vue組件(頁(yè)面/非頁(yè)面組件)中以下函數(shù)都會(huì)在服務(wù)端執(zhí)行,因此代碼容錯(cuò)非常重要,函數(shù)代碼執(zhí)行一旦出錯(cuò),頁(yè)面就掛了

  • fetch
  • asyncData
  • beforeCreate
  • created

1、看的見(jiàn)的錯(cuò)誤

看的見(jiàn)的錯(cuò)誤是指在開(kāi)發(fā)環(huán)境中,你只要在fetch等以上函數(shù)中js執(zhí)行錯(cuò)誤,本地就會(huì)有錯(cuò)誤提示,便于你發(fā)現(xiàn)糾正錯(cuò)誤代碼邏輯

2、未知/看不見(jiàn)的錯(cuò)誤(讓未知錯(cuò)誤暴露出來(lái))

看不見(jiàn)的錯(cuò)誤是指一些異步回調(diào)中的錯(cuò)誤代碼不容易被發(fā)現(xiàn),如果異步行為一直沒(méi)有觸發(fā),那么處理該異步行為的回調(diào)代碼也不會(huì)執(zhí)行;但是對(duì)于處理所有頁(yè)面的api接口請(qǐng)求回調(diào)的錯(cuò)誤排查(主要是做容錯(cuò)處理,使代碼更加健壯,java接口請(qǐng)求404、接口數(shù)據(jù)字段/結(jié)構(gòu)的處理)我們能夠做好,很簡(jiǎn)單,我們只需要在請(qǐng)求攔截器中把請(qǐng)求url更改就可以

$axios.interceptors.request.use(config => {
 // TODO
 // 檢測(cè)由于請(qǐng)求java接口失敗而導(dǎo)致的node應(yīng)用程序錯(cuò)誤
 config.url += '/xxxx'

 return config
})

3、對(duì)于頁(yè)面刷新加載不需要渲染的數(shù)據(jù)的處理

只有頁(yè)面組件asyncData(函數(shù)返回的對(duì)象跟組件data融合),fetch(更新store操作)函數(shù)處理的數(shù)據(jù)跟頁(yè)面綁定后,頁(yè)面刷新加載服務(wù)端才會(huì)渲染;因此不建議組件在beforeCreate,created函數(shù)中通過(guò)請(qǐng)求api接口獲取頁(yè)面刷新加載不需要渲染的數(shù)據(jù),只需要在mounted函數(shù)中處理即可,防止由于代碼錯(cuò)誤導(dǎo)致node應(yīng)用程序出錯(cuò)

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

相關(guān)文章

  • 用js編寫留言板

    用js編寫留言板

    這篇文章主要為大家詳細(xì)介紹了用js編寫留言板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 教你如何通過(guò)JavaScript讀取元素的樣式

    教你如何通過(guò)JavaScript讀取元素的樣式

    這篇文章主要給大家介紹了關(guān)于如何通過(guò)JavaScript讀取元素的樣式,文中通過(guò)實(shí)例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-01-01
  • JavaScript實(shí)現(xiàn)的多種鼠標(biāo)拖放效果

    JavaScript實(shí)現(xiàn)的多種鼠標(biāo)拖放效果

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)的多種鼠標(biāo)拖放效果,涉及JavaScript響應(yīng)鼠標(biāo)事件動(dòng)態(tài)變換頁(yè)面元素屬性的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • 用js生產(chǎn)批量批處理執(zhí)行命令

    用js生產(chǎn)批量批處理執(zhí)行命令

    因?yàn)閺膭e的地方弄到了100個(gè)廣告代碼,但因?yàn)樗睦锩婕尤肓撕芏鄸|西,所以需要批量刪除一個(gè)文件夾和加入我的網(wǎng)站的快捷方式
    2008-07-07
  • JS 實(shí)現(xiàn)請(qǐng)求調(diào)度器

    JS 實(shí)現(xiàn)請(qǐng)求調(diào)度器

    這篇文章主要介紹了JS 實(shí)現(xiàn)請(qǐng)求調(diào)度器的方法,幫助大家更好的理解和學(xué)習(xí)使用js,感興趣的朋友可以了解下
    2021-03-03
  • javaScript實(shí)現(xiàn)一個(gè)隊(duì)列的方法

    javaScript實(shí)現(xiàn)一個(gè)隊(duì)列的方法

    這篇文章主要介紹了javaScript實(shí)現(xiàn)一個(gè)隊(duì)列的方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • JavaScript 32位整型無(wú)符號(hào)操作示例

    JavaScript 32位整型無(wú)符號(hào)操作示例

    所有整數(shù)字變量默認(rèn)都是有符號(hào)整數(shù),JavaScript 進(jìn)行位操作時(shí),是采用32位有符號(hào)整型,這意味著其轉(zhuǎn)換的結(jié)果也是32位有符號(hào)整型
    2013-12-12
  • 微信小程序?qū)崿F(xiàn)簡(jiǎn)單計(jì)算器與秒表

    微信小程序?qū)崿F(xiàn)簡(jiǎn)單計(jì)算器與秒表

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)簡(jiǎn)單計(jì)算器與秒表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • 微信小程序左右滾動(dòng)公告欄效果代碼實(shí)例

    微信小程序左右滾動(dòng)公告欄效果代碼實(shí)例

    這篇文章主要介紹了微信小程序左右滾動(dòng)公告欄效果代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • uniapp中實(shí)現(xiàn)canvas超出屏幕滾動(dòng)查看功能

    uniapp中實(shí)現(xiàn)canvas超出屏幕滾動(dòng)查看功能

    親愛(ài)的小伙伴,當(dāng)你需要在uniapp中使用canvas繪制一個(gè)超長(zhǎng)圖,就類似于橫向的流程圖時(shí),這個(gè)canvas超出屏幕部分拖動(dòng)屏幕查看會(huì)變得十分棘手,怎么解決這個(gè)問(wèn)題呢,下面小編給大家介紹uniapp中實(shí)現(xiàn)canvas超出屏幕滾動(dòng)查看功能,感興趣的朋友一起看看吧
    2024-03-03

最新評(píng)論