html前端如何缓存页面,Nuxt中如何做页面html缓存
Nuxt是一款基于Vue的服務(wù)端渲染SSR框架
在Nuxt框架的API中,有一個(gè)叫 serverMiddleware 的服務(wù)端中間件,我們可以利用它在返回首屏html前做一些緩存的處理
在這之前我們需要了解一個(gè)叫LRU的算法,LRU是一種緩存淘汰算法,用鏈表存儲數(shù)據(jù),最新插入的數(shù)據(jù)會(huì)排在鏈表頭部,已緩存的數(shù)據(jù)收到訪問也會(huì)被移到鏈表的頭部,鏈表有長度限制,滿了的時(shí)候排在尾部的數(shù)組將被丟棄。
進(jìn)入正題,實(shí)現(xiàn)html緩存我們需要兩個(gè)包,一個(gè)是lru-cache,一個(gè)是etag
(lru-cache是別人封裝好的一個(gè)lru存儲類,etag是用來為實(shí)體內(nèi)容產(chǎn)生一個(gè)strong etag)
建一個(gè)pageCache.js,引入這兩個(gè)包
import LRU from 'lru-cache';
import etag from 'etag';
const cacheStore = new LRU({
max: 10000, // 設(shè)置最大的緩存?zhèn)€數(shù)
maxAge: 5 * 60 * 1000 // 5分鐘
});
復(fù)制代碼
我們可以根據(jù)需要調(diào)整max和maxAge,來控制LRU緩存
接著我們來自定義一個(gè)serverMiddleware
import LRU from 'lru-cache';
import etag from 'etag';
const cacheStore = new LRU({
max: 10000, // 設(shè)置最大的緩存?zhèn)€數(shù)
maxAge: 5 * 60 * 1000 // 5分鐘
});
export default function(req, res, next) {
const isDev = process.env.NODE_ENV === 'development'
// 開發(fā)環(huán)境為了方便開發(fā),就不走緩存
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) {
// 如果命中緩存,則看是否命中協(xié)商緩存,是則直接返回304,不是則返回200和數(shù)據(jù)
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 {
// 如果緩存沒命中,則返回請求的內(nèi)容
// 緩存原先的res.end
res.original_end = res.end
// 重寫res.end方法,nuxt服務(wù)器響應(yīng)時(shí)會(huì)調(diào)用res.end
res.end = function(data) {
if (res.statusCode === 200) {
// 將該頁面請求html內(nèi)容存進(jìn)LRU
// 第三個(gè)參數(shù)緩存時(shí)間傳undefined則走起初cacheStore定義時(shí)的5分鐘
cacheStore.set(key, { etag: etag(data), value: data }, undefined)
}
// html設(shè)置客戶端強(qiáng)緩存60s
res.setHeader('Cache-Control', 'private, max-age=60')
// 最終返回請求的內(nèi)容
return res.original_end(data, 'utf-8')
}
retun next()
}
}
復(fù)制代碼
然后我們在nuxt.config.js內(nèi)配上這個(gè)中間件就可以了
serverMiddleware: [ '~/../pageCache']
復(fù)制代碼
看起來好像OK了
ちょっと待って
我們頁面url不可避免會(huì)有參數(shù),而且參數(shù)可能會(huì)影響頁面的內(nèi)容,如果我們只是用頁面url的pathname做緩存的key的話,會(huì)導(dǎo)致不同參數(shù)的url訪問到的內(nèi)容都命中了同一個(gè)緩存,那該怎么辦呢?很簡單,我們用 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;
}
復(fù)制代碼
大功告成!
總結(jié)
以上是生活随笔為你收集整理的html前端如何缓存页面,Nuxt中如何做页面html缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Observer 模式
- 下一篇: HTML 显示特殊字符时转义操作