html前端如何缓存页面,Nuxt中如何做页面html缓存
Nuxt是一款基于Vue的服務端渲染SSR框架
在Nuxt框架的API中,有一個叫 serverMiddleware 的服務端中間件,我們可以利用它在返回首屏html前做一些緩存的處理
在這之前我們需要了解一個叫LRU的算法,LRU是一種緩存淘汰算法,用鏈表存儲數據,最新插入的數據會排在鏈表頭部,已緩存的數據收到訪問也會被移到鏈表的頭部,鏈表有長度限制,滿了的時候排在尾部的數組將被丟棄。
進入正題,實現html緩存我們需要兩個包,一個是lru-cache,一個是etag
(lru-cache是別人封裝好的一個lru存儲類,etag是用來為實體內容產生一個strong etag)
建一個pageCache.js,引入這兩個包
import LRU from 'lru-cache';
import etag from 'etag';
const cacheStore = new LRU({
max: 10000, // 設置最大的緩存個數
maxAge: 5 * 60 * 1000 // 5分鐘
});
復制代碼
我們可以根據需要調整max和maxAge,來控制LRU緩存
接著我們來自定義一個serverMiddleware
import LRU from 'lru-cache';
import etag from 'etag';
const cacheStore = new LRU({
max: 10000, // 設置最大的緩存個數
maxAge: 5 * 60 * 1000 // 5分鐘
});
export default function(req, res, next) {
const isDev = process.env.NODE_ENV === 'development'
// 開發環境為了方便開發,就不走緩存
if (isDev) {
return next()
}
// 此次我們只針對html做緩存
if (req.headers.accept &&
(req.headers.accept.indexOf('text/html') === -1
&& req.headers.accept.indexOf('application/xhtml+xml') === -1
&& req.headers.accept.indexOf('application/xml') === -1)
) {
return next()
}
// 用頁面url的pathname作為LRU緩存的key值
let key = req._parsedOriginalUrl.pathname
// 獲取LRU中的緩存
const { etag: curEtag, value } = cacheStore.get(key) || {}
if (value) {
// 如果命中緩存,則看是否命中協商緩存,是則直接返回304,不是則返回200和數據
if (curEtag === req.hedaers['if-none-match']) {
res.writeHead(304)
return res.end()
} else {
res.writeHead(200, {
'Content-Type': 'text/html;charset=utf-8',
'Cache-Control': 'private, max-age=60',
'Etag': curEtag
})
}
} else {
// 如果緩存沒命中,則返回請求的內容
// 緩存原先的res.end
res.original_end = res.end
// 重寫res.end方法,nuxt服務器響應時會調用res.end
res.end = function(data) {
if (res.statusCode === 200) {
// 將該頁面請求html內容存進LRU
// 第三個參數緩存時間傳undefined則走起初cacheStore定義時的5分鐘
cacheStore.set(key, { etag: etag(data), value: data }, undefined)
}
// html設置客戶端強緩存60s
res.setHeader('Cache-Control', 'private, max-age=60')
// 最終返回請求的內容
return res.original_end(data, 'utf-8')
}
retun next()
}
}
復制代碼
然后我們在nuxt.config.js內配上這個中間件就可以了
serverMiddleware: [ '~/../pageCache']
復制代碼
看起來好像OK了
ちょっと待って
我們頁面url不可避免會有參數,而且參數可能會影響頁面的內容,如果我們只是用頁面url的pathname做緩存的key的話,會導致不同參數的url訪問到的內容都命中了同一個緩存,那該怎么辦呢?很簡單,我們用 pathname+query 作為緩存的key就可以了
import { parse, stringify } from 'querystring';
let key = req._parsedOriginalUrl.pathname;
//是否是需要緩存的x頁面
if(req._parsedOriginalUrl.pathname.toLowerCase().indexOf('/x') >= 0){
const query = parse(req._parsedUrl.query)
const queryStr = stringify({ ...query })
key = key + '?' + queryStr;
}
復制代碼
大功告成!
總結
以上是生活随笔為你收集整理的html前端如何缓存页面,Nuxt中如何做页面html缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Observer 模式
- 下一篇: Spring Data JPA 从入门到