緩存控制Cache-Control
Cache-Control是Web性能優(yōu)化的一種,能加速HTTP請求與響應(yīng)。
服務(wù)器中設(shè)置響應(yīng)頭:
response.setHeader('Cache-Control', 'max-age=30')
30秒內(nèi)不會再次請求瀏覽器從內(nèi)存中把請求的內(nèi)容拿給你。
例如,向服務(wù)器請求一個很大的main.js文件,下載這個文件需要較長時間,服務(wù)器在返回文件的同時在響應(yīng)頭中設(shè)置Cache-Control: max-age=30。30秒內(nèi)再次請求同樣的URL,瀏覽器不會再次發(fā)起請求,而是直接從內(nèi)存中返回上次的main.js文件,這樣就節(jié)約了再次下載文件的時間。30秒后再次請求這個main.js,服務(wù)器返回文件的同時再次設(shè)置Cache-Control,如此重復(fù)。
如何更新緩存
一般設(shè)置Cache-Control的時間都會很久,比如一年,十年,盡量不再發(fā)請求。那么會有一個問題:如果頁面有更新,用戶沒有辦法獲取最新的版本。
所以入口處(首頁,html)不能設(shè)置Cache-Control。
如果全都設(shè)置了Cache-Control,用戶每次訪問都直接從內(nèi)存中讀取內(nèi)容,不會向服務(wù)器發(fā)起任何請求,獲取不到更新。
而留著入口不用緩存,每次請求首頁都向服務(wù)器發(fā)起請求,如果其他文件有更新,就在入口處把URL變一下(不改變請求路徑,例如加一個查詢參數(shù)),這樣瀏覽器就不會使用緩存,而是下載最新的版本,再把新版本緩存下來。
改變URL,例如,加一個查詢參數(shù):
<link rel="stylesheet" href="./css/default.css">
//更新,變成
<link rel="stylesheet" href="./css/default.css/?v=2">
//再更新
<link rel="stylesheet" href="./css/default.css/?v=3">
上面代碼還是在訪問/css,但是URL不是以前的URL了,所以瀏覽器不會使用緩存,而是下載新的css。
Expires
Expires頭制定了一個日期/時間,在這個日期/時間之后,HTTP響應(yīng)被認(rèn)為是過時的,不再用緩存,重新請求。
如果還設(shè)置了"max-age"或"s-max-age"指令的Cache-Control響應(yīng)頭,那么Expires頭就會被忽略。
Cache-Control是設(shè)置多長時間后過期,是一個時間長度;
Expires是設(shè)置什么時候過期,是一個時間點(diǎn)。
但是Expires設(shè)置的時間點(diǎn)指的是本地時間,如果用戶本地時間錯亂就會出問題。
ETag
首先了解一下MD5。
MD5是一種摘要算法,用于確保信息傳輸完整一致。
簡單來說,MD5把信息變成一個字符串,信息傳輸后再次用MD5解析,任何一點(diǎn)變化都會生成一個不同的字符串,且內(nèi)容差異越小,生成的結(jié)果差異越大,把微小的差異放大。
MD5
ETag HTTP響應(yīng)頭是資源特定版本標(biāo)識符。
把文件的MD5放到ETag里設(shè)置響應(yīng)頭:
let fileMd5 = md5(string)
response.setHeader('ETag', fileMd5)
在請求這個文件時,響應(yīng)頭里有了ETag: Md5的值,
再次請求同意個文件時,請求頭里帶著If-None-Match: Md5值,
也就是再次請求時帶著一個版本號(Md5的值),如果版本號與上次相同,說明文件沒有更新,不需要重新下載。
let fileMd5 = md5(string)
response.setHeader('ETag', fileMd5)
if(request.headers['If-None-Match'] === fileMd5){
//沒有響應(yīng)體
response.statusCode = 304 //Not Modefied
}else{
//有響應(yīng)體
response.write(string)
}
用Cache-Control直接不發(fā)請求,
用ETag,要發(fā)請求,如果MD5一樣,不下載。