Vue.js SSR 緩存

2021-01-07 15:40 更新

雖然 Vue 的服務(wù)器端渲染 (SSR) 相當快速,但是由于創(chuàng)建組件實例和虛擬 DOM 節(jié)點的開銷,無法與純基于字符串拼接 (pure string-based) 的模板的性能相當。在 SSR 性能至關(guān)重要的情況下,明智地利用緩存策略,可以極大改善響應(yīng)時間并減少服務(wù)器負載。

頁面級別緩存 (Page-level Caching)

在大多數(shù)情況下,服務(wù)器渲染的應(yīng)用程序依賴于外部數(shù)據(jù),因此本質(zhì)上頁面內(nèi)容是動態(tài)的,不能持續(xù)長時間緩存。然而,如果內(nèi)容不是用戶特定 (user-specific)(即對于相同的 URL,總是為所有用戶渲染相同的內(nèi)容),我們可以利用名為 micro-caching 的緩存策略,來大幅度提高應(yīng)用程序處理高流量的能力。

這通常在 Nginx 層完成,但是我們也可以在 Node.js 中實現(xiàn)它:

const microCache = LRU({
  max: 100,
  maxAge: 1000 // 重要提示:條目在 1 秒后過期。
})


const isCacheable = req => {
  // 實現(xiàn)邏輯為,檢查請求是否是用戶特定(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)
    }
  })
})

由于內(nèi)容緩存只有一秒鐘,用戶將無法查看過期的內(nèi)容。然而,這意味著,對于每個要緩存的頁面,服務(wù)器最多只能每秒執(zhí)行一次完整渲染。

組件級別緩存 (Component-level Caching)

vue-server-renderer 內(nèi)置支持組件級別緩存 (component-level caching)。要啟用組件級別緩存,你需要在創(chuàng)建 renderer 時提供具體緩存實現(xiàn)方式(cache implementation) 。典型做法是傳入 lru-cache

const LRU = require('lru-cache')


const renderer = createRenderer({
  cache: LRU({
    max: 10000,
    maxAge: ...
  })
})

然后,你可以通過實現(xiàn) serverCacheKey 函數(shù)來緩存組件。

export default {
  name: 'item', // 必填選項
  props: ['item'],
  serverCacheKey: props => props.item.id,
  render (h) {
    return h('div', this.item.id)
  }
}

請注意,可緩存組件還必須定義一個唯一的 name 選項。通過使用唯一的名稱,每個緩存鍵 (cache key) 對應(yīng)一個組件:你無需擔心兩個組件返回同一個 key。

serverCacheKey 返回的 key 應(yīng)該包含足夠的信息,來表示渲染結(jié)果的具體情況。如果渲染結(jié)果僅由 props.item.id 決定,則上述是一個很好的實現(xiàn)。但是,如果具有相同 id 的 item 可能會隨時間而變化,或者如果渲染結(jié)果依賴于其他 prop,則需要修改 serverCacheKey 的實現(xiàn),以考慮其他變量。

返回常量將導(dǎo)致組件始終被緩存,這對純靜態(tài)組件是有好處的。

何時使用組件緩存

如果 renderer 在組件渲染過程中進行緩存命中,那么它將直接重新使用整個子樹的緩存結(jié)果。這意味著在以下情況,你應(yīng)該緩存組件:

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

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

serverCacheKey: props => props.item.id + '::' + props.item.last_updated
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號