1)瀏覽器緩存策略
瀏覽器每次發(fā)起請求時,先在本地緩存中查找結(jié)果以及緩存標(biāo)識,根據(jù)緩存標(biāo)識來判斷是否使用本地緩存。如果緩存有效,則使
用本地緩存;否則,則向服務(wù)器發(fā)起請求并攜帶緩存標(biāo)識。根據(jù)是否需向服務(wù)器發(fā)起HTTP請求,將緩存過程劃分為兩個部分:
強制緩存和協(xié)商緩存,強緩優(yōu)先于協(xié)商緩存。
- 強緩存,服務(wù)器通知瀏覽器一個緩存時間,在緩存時間內(nèi),下次請求,直接用緩存,不在時間內(nèi),執(zhí)行比較緩存策略。
- 協(xié)商緩存,讓客戶端與服務(wù)器之間能實現(xiàn)緩存文件是否更新的驗證、提升緩存的復(fù)用率,將緩存信息中的Etag和Last-Modified
通過請求發(fā)送給服務(wù)器,由服務(wù)器校驗,返回304狀態(tài)碼時,瀏覽器直接使用緩存。
HTTP緩存都是從第二次請求開始的:
第一次請求資源時,服務(wù)器返回資源,并在response header中回傳資源的緩存策略;
-
第二次請求時,瀏覽器判斷這些請求參數(shù),擊中強緩存就直接200,否則就把請求參數(shù)加到request header頭中傳給服務(wù)器,看是否擊中協(xié)商緩存,擊中則返回304,否則服務(wù)器會返回新的資源。這是緩存運作的一個整體流程圖:
image.png
2)強緩存 強緩存命中則直接讀取瀏覽器本地的資源,在network中顯示的是from memory或者from disk
控制強制緩存的字段有:Cache-Control(http1.1)和Expires(http1.0)
Cache-control是一個相對時間,用以表達(dá)自上次請求正確的資源之后的多少秒的時間段內(nèi)緩存有效。
Expires是一個絕對時間。用以表達(dá)在這個時間點之前發(fā)起請求可以直接從瀏覽器中讀取數(shù)據(jù),而無需發(fā)起請求
Cache-Control的優(yōu)先級比Expires的優(yōu)先級高。前者的出現(xiàn)是為了解決Expires在瀏覽器時間被手動更改導(dǎo)致緩存判斷錯誤的問題。
如果同時存在則使用Cache-control。
3)強緩存-expires
該字段是服務(wù)器響應(yīng)消息頭字段,告訴瀏覽器在過期時間之前可以直接從瀏覽器緩存中存取數(shù)據(jù)。
Expires 是 HTTP 1.0 的字段,表示緩存到期時間,是一個絕對的時間 (當(dāng)前時間+緩存時間)。在響應(yīng)消息頭中,設(shè)置這個字段之后,就可以告訴瀏覽器,在未過期之前不需要再次請求。
由于是絕對時間,用戶可能會將客戶端本地的時間進(jìn)行修改,而導(dǎo)致瀏覽器判斷緩存失效,重新請求該資源。此外,即使不考慮修改,時差或者誤差等因素也可能造成客戶端與服務(wù)端的時間不一致,致使緩存失效。
-
優(yōu)勢特點
- 1、HTTP 1.0 產(chǎn)物,可以在HTTP 1.0和1.1中使用,簡單易用。
- 2、以時刻標(biāo)識失效時間。
-
劣勢問題
- 1、時間是由服務(wù)器發(fā)送的(UTC),如果服務(wù)器時間和客戶端時間存在不一致,可能會出現(xiàn)問題。
- 2、存在版本問題,到期之前的修改客戶端是不可知的。
4)強緩存-cache-control
已知Expires的缺點之后,在HTTP/1.1中,增加了一個字段Cache-control,該字段表示資源緩存的最大有效時間,在該時間內(nèi),客戶端不需要向服務(wù)器發(fā)送請求。
-
這兩者的區(qū)別就是前者是絕對時間,而后者是相對時間。下面列舉一些
Cache-control字段常用的值:(完整的列表可以查看MDN)-
max-age:即最大有效時間。 -
must-revalidate:如果超過了max-age的時間,瀏覽器必須向服務(wù)器發(fā)送請求,驗證資源是否還有效。 -
no-cache:不使用強緩存,需要與服務(wù)器驗證緩存是否新鮮。 -
no-store: 真正意義上的“不要緩存”。所有內(nèi)容都不走緩存,包括強制和對比。 -
public:所有的內(nèi)容都可以被緩存 (包括客戶端和代理服務(wù)器, 如 CDN) -
private:所有的內(nèi)容只有客戶端才可以緩存,代理服務(wù)器不能緩存。默認(rèn)值。
-
Cache-control 的優(yōu)先級高于 Expires,為了兼容 HTTP/1.0 和 HTTP/1.1,實際項目中兩個字段都可以設(shè)置。
-
該字段可以在請求頭或者響應(yīng)頭設(shè)置,可組合使用多種指令:
-
可緩存性:
- public:瀏覽器和緩存服務(wù)器都可以緩存頁面信息
- private:default,代理服務(wù)器不可緩存,只能被單個用戶緩存
- no-cache:瀏覽器器和服務(wù)器都不應(yīng)該緩存頁面信息,但仍可緩存,只是在緩存前需要向服務(wù)器確認(rèn)資源是否被更改??膳浜蟨rivate,
過期時間設(shè)置為過去時間。 - only-if-cache:客戶端只接受已緩存的響應(yīng)
-
到期
- max-age=:緩存存儲的最大周期,超過這個周期被認(rèn)為過期。
- s-maxage=:設(shè)置共享緩存,比如can。會覆蓋max-age和expires。
- max-stale[=]:客戶端愿意接收一個已經(jīng)過期的資源
- min-fresh=:客戶端希望在指定的時間內(nèi)獲取最新的響應(yīng)
- stale-while-revalidate=:客戶端愿意接收陳舊的響應(yīng),并且在后臺一部檢查新的響應(yīng)。時間代表客戶端愿意接收陳舊響應(yīng)
的時間長度。 - stale-if-error=:如新的檢測失敗,客戶端則愿意接收陳舊的響應(yīng),時間代表等待時間。
-
重新驗證和重新加載
- must-revalidate:如頁面過期,則去服務(wù)器進(jìn)行獲取。
- proxy-revalidate:用于共享緩存。
- immutable:響應(yīng)正文不隨時間改變。
-
其他
- no-store:絕對禁止緩存
- no-transform:不得對資源進(jìn)行轉(zhuǎn)換和轉(zhuǎn)變。例如,不得對圖像格式進(jìn)行轉(zhuǎn)換。
-
可緩存性:
-
優(yōu)勢特點
- 1、HTTP 1.1 產(chǎn)物,以時間間隔標(biāo)識失效時間,解決了Expires服務(wù)器和客戶端相對時間的問題。
- 2、比Expires多了很多選項設(shè)置。
-
劣勢問題
- 1、存在版本問題,到期之前的修改客戶端是不可知的。
5)協(xié)商緩存
- 協(xié)商緩存的狀態(tài)碼由服務(wù)器決策返回200或者304
- 當(dāng)瀏覽器的強緩存失效的時候或者請求頭中設(shè)置了不走強緩存,并且在請求頭中設(shè)置了If-Modified-Since 或者 If-None-Match 的時候,會將這兩個屬性值到服務(wù)端去驗證是否命中協(xié)商緩存,如果命中了協(xié)商緩存,會返回 304 狀態(tài),加載瀏覽器緩存,并且響應(yīng)頭會設(shè)置 Last-Modified 或者 ETag 屬性。
- 對比緩存在請求數(shù)上和沒有緩存是一致的,但如果是 304 的話,返回的僅僅是一個狀態(tài)碼而已,并沒有實際的文件內(nèi)容,因此 在響應(yīng)體體積上的節(jié)省是它的優(yōu)化點。
- 協(xié)商緩存有 2 組字段(不是兩個),控制協(xié)商緩存的字段有:Last-Modified/If-Modified-since(http1.0)和Etag/If-None-match(http1.1)
- Last-Modified/If-Modified-since表示的是服務(wù)器的資源最后一次修改的時間;Etag/If-None-match表示的是服務(wù)器資源的唯一標(biāo)
識,只要資源變化,Etag就會重新生成。 - Etag/If-None-match的優(yōu)先級比Last-Modified/If-Modified-since高。
6)協(xié)商緩存-協(xié)商緩存-Last-Modified/If-Modified-since
- 1.服務(wù)器通過
Last-Modified字段告知客戶端,資源最后一次被修改的時間,例如Last-Modified: Mon, 10 Nov 2018 09:10:11 GMT - 2.瀏覽器將這個值和內(nèi)容一起記錄在緩存數(shù)據(jù)庫中。
- 3.下一次請求相同資源時時,瀏覽器從自己的緩存中找出“不確定是否過期的”緩存。因此在請求頭中將上次的
Last-Modified的值寫入到請求頭的If-Modified-Since字段 - 4.服務(wù)器會將
If-Modified-Since的值與Last-Modified字段進(jìn)行對比。如果相等,則表示未修改,響應(yīng) 304;反之,則表示修改了,響應(yīng) 200 狀態(tài)碼,并返回數(shù)據(jù)。 - 優(yōu)勢特點
- 1、不存在版本問題,每次請求都會去服務(wù)器進(jìn)行校驗。服務(wù)器對比最后修改時間如果相同則返回304,不同返回200以及資源內(nèi)容。
- 劣勢問題
- 2、只要資源修改,無論內(nèi)容是否發(fā)生實質(zhì)性的變化,都會將該資源返回客戶端。例如周期性重寫,這種情況下該資源包含的數(shù)據(jù)實際上一樣的。
- 3、以時刻作為標(biāo)識,無法識別一秒內(nèi)進(jìn)行多次修改的情況。 如果資源更新的速度是秒以下單位,那么該緩存是不能被使用的,因為它的時間單位最低是秒。
- 4、某些服務(wù)器不能精確的得到文件的最后修改時間。
- 5、如果文件是通過服務(wù)器動態(tài)生成的,那么該方法的更新時間永遠(yuǎn)是生成的時間,盡管文件可能沒有變化,所以起不到緩存的作用。
7)協(xié)商緩存-Etag/If-None-match
- 為了解決上述問題,出現(xiàn)了一組新的字段
Etag和If-None-Match -
Etag存儲的是文件的特殊標(biāo)識(一般都是 hash 生成的),服務(wù)器存儲著文件的Etag字段。之后的流程和Last-Modified一致,只是Last-Modified字段和它所表示的更新時間改變成了Etag字段和它所表示的文件 hash,把If-Modified-Since變成了If-None-Match。服務(wù)器同樣進(jìn)行比較,命中返回 304, 不命中返回新資源和 200。 - 瀏覽器在發(fā)起請求時,服務(wù)器返回在Response header中返回請求資源的唯一標(biāo)識。在下一次請求時,會將上一次返回的Etag值賦值給If-No-Matched并添加在Request Header中。服務(wù)器將瀏覽器傳來的if-no-matched跟自己的本地的資源的ETag做對比,如果匹配,則返回304通知瀏覽器讀取本地緩存,否則返回200和更新后的資源。
- Etag 的優(yōu)先級高于 Last-Modified。
- 優(yōu)勢特點
- 1、可以更加精確的判斷資源是否被修改,可以識別一秒內(nèi)多次修改的情況。
- 2、不存在版本問題,每次請求都回去服務(wù)器進(jìn)行校驗。
- 劣勢問題
- 1、計算ETag值需要性能損耗。
- 2、分布式服務(wù)器存儲的情況下,計算ETag的算法如果不一樣,會導(dǎo)致瀏覽器從一臺服務(wù)器上獲得頁面內(nèi)容后到另外一臺服務(wù)器上進(jìn)行驗證時現(xiàn)ETag不匹配的情況。
