強緩存和協(xié)商緩存

緩存正什,作為我們開發(fā)過程中經(jīng)常碰到的一樣?xùn)|西移剪,相信很多小伙伴和我一樣對它熟悉又陌生,各種 expires 瓤摧、Etag 好像都知道竿裂,卻又好像無法把它講清楚,所以本篇文章就來總結(jié)整理下照弥。

一腻异、緩存

首先,什么是緩存这揣?我的理解悔常,緩存就是一個資源副本。當我們向服務(wù)器請求資源后给赞,會根據(jù)情況將資源 copy 一份副本存在本地机打,以方便下次讀取。它與本地存儲 localStorage 片迅、cookie 等不同残邀,本地存儲更多是數(shù)據(jù)記錄,存儲量較小,為了本地操作方便芥挣。而緩存更多是為了減少資源請求驱闷,多用于存儲文件,存儲量相對較大空免。

那緩存有啥用呢空另?緩存最根本的作用就是減少沒必要請求。有些資源蹋砚,比如用戶頭像圖片扼菠,很久才改變一次,但每次都要去請求這張一樣的圖片坝咐,通信一來一回增加了頁面的顯示時長娇豫,過多沒必要請求也增加了服務(wù)器的壓力。如果把這張圖片直接緩存在本地畅厢,那每次就可以直接本地讀取加載,不再發(fā)起請求氮昧。所以緩存的好處也就顯而易見了框杜,減少了時長從而優(yōu)化用戶體驗,也減少了流量消耗袖肥,減輕了服務(wù)器的壓力咪辱。

那么,緩存有哪些呢椎组?就瀏覽器而言油狂,一般緩存我們分為四類,按瀏覽器讀取優(yōu)先級順序依次為:Memory Cache寸癌、Service Worker Cache专筷、HTTP CachePush Cache蒸苇。而本篇文章主要講的就是 HTTP Cache 磷蛹,其他有興趣可以自行搜索。

二溪烤、HTTP Cache

HTTP Cache 是我們開發(fā)中接觸最多的緩存味咳,它分為強緩存和協(xié)商緩存。

  1. 強緩存:直接從本地副本比對讀取檬嘀,不去請求服務(wù)器槽驶,返回的狀態(tài)碼是 200
  2. 協(xié)商緩存:會去服務(wù)器比對鸳兽,若沒改變才直接讀取本地緩存掂铐,返回的狀態(tài)碼是 304

(一)、強緩存

強緩存主要包括 expirescache-control堡纬。

1聂受、expires

expiresHTTP1.0 中定義的緩存字段。當我們請求一個資源烤镐,服務(wù)器返回時蛋济,可以在 Response Headers 中增加 expires 字段表示資源的過期時間。

expires: Thu, 03 Jan 2019 11:43:04 GMT

它是一個時間戳(準確點應(yīng)該叫格林尼治時間)炮叶,當客戶端再次請求該資源的時候碗旅,會把客戶端時間與該時間戳進行對比,如果大于該時間戳則已過期镜悉,否則直接使用該緩存資源祟辟。

但是,有個大問題侣肄,發(fā)送請求時是使用的客戶端時間去對比旧困。一是客戶端和服務(wù)端時間可能快慢不一致,另一方面是客戶端的時間是可以自行修改的(比如瀏覽器是跟隨系統(tǒng)時間的稼锅,修改系統(tǒng)時間會影響到)吼具,所以不一定滿足預(yù)期。

2矩距、cache-control

正由于上面說的可能存在的問題拗盒,HTTP1.1 新增了 cache-control 字段來解決該問題,所以當 cache-controlexpires 都存在時锥债,cache-control 優(yōu)先級更高陡蝇。該字段是一個時間長度,單位秒哮肚,表示該資源過了多少秒后失效登夫。當客戶端請求資源的時候,發(fā)現(xiàn)該資源還在有效時間內(nèi)則使用該緩存允趟,它不依賴客戶端時間悼嫉。cache-control 主要有 max-ages-maxagepublicprivate拼窥、no-cacheno-store 等值戏蔑。

cache-control: public, max-age=3600, s-maxage=3600 
  1. max-ages-maxage
    兩者是 cache-control 的主要字段,它們是一個數(shù)字鲁纠,表示資源過了多少秒之后變?yōu)闊o效总棵。在瀏覽器中,max-ages-maxage 都起作用改含,而且 s-maxage 的優(yōu)先級高于 max-age情龄。在代理服務(wù)器中,只有 s-maxage 起作用。 可以通過設(shè)置 max-age 為 0 表示立馬過期來向服務(wù)器請求資源骤视。

  2. publicprivate
    public 表示該資源可以被所有客戶端和代理服務(wù)器緩存鞍爱,而 private 表示該資源僅能客戶端緩存。默認值是 private专酗,當設(shè)置了 s-maxage 的時候表示允許代理服務(wù)器緩存睹逃,相當于 public休偶。

  3. no-cacheno-store
    no-cache 表示的是不直接詢問瀏覽器緩存情況剃氧,而是去向服務(wù)器驗證當前資源是否更新(即協(xié)商緩存)黍少。no-store 則更狠路捧,完全不使用緩存策略,不緩存請求或響應(yīng)的任何內(nèi)容谎脯,直接向服務(wù)器請求最新丁寄。由于兩者都不考慮緩存情況而是直接與服務(wù)器交互喻圃,所以當 no-cacheno-store 存在時會直接忽略 max-age 等蒋纬。

3猎荠、pragma

既然講到了 no-cacheno-store,就順便把 pragma 也講了蜀备。他的值有 no-cacheno-store关摇,表示意思同 cache-control,優(yōu)先級高于 cache-controlexpires琼掠,即三者同時出現(xiàn)時,先看 pragma -> cache-control -> expires停撞。

pragma: no-cache

(二)瓷蛙、協(xié)商緩存

上面的 expirescache-control 都會訪問本地緩存直接驗證看是否過期,如果沒過期直接使用本地緩存戈毒,并返回 200艰猬。但如果設(shè)置了 no-cacheno-store 則本地緩存會被忽略,會去請求服務(wù)器驗證資源是否更新埋市,如果沒更新才繼續(xù)使用本地緩存冠桃,此時返回的是 304,這就是協(xié)商緩存道宅。協(xié)商緩存主要包括 last-modifiedetag食听。

1、last-modified

last-modified 記錄資源最后修改的時間污茵。啟用后樱报,請求資源之后的響應(yīng)頭會增加一個 last-modified 字段,如下:

last-modified: Thu, 20 Dec 2018 11:36:00 GMT

當再次請求該資源時泞当,請求頭中會帶有 if-modified-since 字段迹蛤,值是之前返回的 last-modified 的值,如:if-modified-since:Thu, 20 Dec 2018 11:36:00 GMT。服務(wù)端會對比該字段和資源的最后修改時間盗飒,若一致則證明沒有被修改嚷量,告知瀏覽器可直接使用緩存并返回 304;若不一致則直接返回修改后的資源逆趣,并修改 last-modified 為新的值蝶溶。

last-modified 有以下兩個缺點:

  • 只要編輯了,不管內(nèi)容是否真的有改變汗贫,都會以這最后修改的時間作為判斷依據(jù)身坐,當成新資源返回,從而導(dǎo)致了沒必要的請求響應(yīng)落包,而這正是緩存本來的作用即避免沒必要的請求部蛇。
  • 時間的精確度只能到秒,如果在一秒內(nèi)的修改是檢測不到更新的咐蝇,仍會告知瀏覽器使用舊的緩存涯鲁。
2、etag

為了解決 last-modified 上述問題有序,有了 etag抹腿。 etag 會基于資源的內(nèi)容編碼生成一串唯一的標識字符串,只要內(nèi)容不同旭寿,就會生成不同的 etag警绩。啟用 etag 之后,請求資源后的響應(yīng)返回會增加一個 etag 字段盅称,如下:

etag: "FllOiaIvA1f-ftHGziLgMIMVkVw_"

當再次請求該資源時肩祥,請求頭會帶有 if-none-match 字段,值是之前返回的 etag 值缩膝,如:if-none-match:"FllOiaIvA1f-ftHGziLgMIMVkVw_"混狠。服務(wù)端會根據(jù)該資源當前的內(nèi)容生成對應(yīng)的標識字符串和該字段進行對比,若一致則代表未改變可直接使用本地緩存并返回 304疾层;若不一致則返回新的資源(狀態(tài)碼200)并修改返回的 etag 字段為新的值将饺。

可以看出 etaglast-modified 更加精準地感知了變化,所以 etag 優(yōu)先級也更高痛黎。不過從上面也可以看出 etag 存在的問題予弧,就是每次生成標識字符串會增加服務(wù)器的開銷。所以要如何使用 last-modifiedetag 還需要根據(jù)具體需求進行權(quán)衡湖饱。

三桌肴、訪問刷新分析

我們將訪問和刷新分為以下三種情況:

  • 標簽進入、輸入url回車進入
  • 按刷新按鈕琉历、F5 刷新坠七、網(wǎng)頁右鍵“重新加載”
  • ctrl + F5 強制刷新

假設(shè)當前有這么一個 index 頁面水醋,返回的響應(yīng)信息如下:

cache-control: max-age=72000
expires: Tue, 20 Nov 2018 20:41:14 GMT
last-modified: Tue, 20 Nov 2018 00:41:14 GMT
1、標簽進入彪置、輸入url回車進入

這種情況下會根據(jù)實際設(shè)計的緩存策略去判斷拄踪。

  1. 由于該例沒有設(shè)置 no-cacheno-store,所以默認先走強緩存路線拳魁。根據(jù) cache-controlexpires 優(yōu)先級低)判斷緩存是否過期惶桐,若沒有過期則此時返回 200(from cache)
  2. 若本地緩存已經(jīng)過期再走協(xié)商緩存路線潘懊,根據(jù)之前的 last-modified 值去與服務(wù)器比對姚糊,若這個時間之后沒有改過則去讀取本地緩存,返回 304(not modified)授舟。
  3. 否則返回新的資源救恨,狀態(tài)碼 200(ok),并更新返回響應(yīng)的 last-modified 值释树。
2肠槽、按刷新按鈕、F5 刷新奢啥、網(wǎng)頁右鍵“重新加載”

這種情況下秸仙,實際是瀏覽器將 cache-controlmax-age 直接設(shè)置成了 0,讓緩存立即過期桩盲,直接走協(xié)商緩存路線寂纪。發(fā)送的請求頭如下:

cache-control: max-age=0
if-modified-since: Tue, 20 Nov 2018 00:41:14 GMT
3、ctrl + F5 強制刷新

強制刷新的情況下赌结,瀏覽器會強行設(shè)置 no-cache捞蛋,強制獲取最新的資源,就連 if-modified-since 等其他緩存協(xié)議字段都會被吃掉姑曙。此時發(fā)送的請求頭如下:

cache-control: no-cache
pragma: no-cache

參考文章

  1. 緩存詳解
  2. HTTP緩存控制小結(jié)
  3. Cache-control
  4. 前端性能優(yōu)化原理與實踐
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末襟交,一起剝皮案震驚了整個濱河市迈倍,隨后出現(xiàn)的幾起案子伤靠,更是在濱河造成了極大的恐慌,老刑警劉巖啼染,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宴合,死亡現(xiàn)場離奇詭異,居然都是意外死亡迹鹅,警方通過查閱死者的電腦和手機卦洽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斜棚,“玉大人阀蒂,你說我怎么就攤上這事该窗。” “怎么了蚤霞?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵酗失,是天一觀的道長。 經(jīng)常有香客問我昧绣,道長规肴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任夜畴,我火速辦了婚禮拖刃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贪绘。我一直安慰自己兑牡,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布兔簇。 她就那樣靜靜地躺著发绢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垄琐。 梳的紋絲不亂的頭發(fā)上边酒,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音狸窘,去河邊找鬼墩朦。 笑死,一個胖子當著我的面吹牛翻擒,可吹牛的內(nèi)容都是我干的氓涣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陋气,長吁一口氣:“原來是場噩夢啊……” “哼劳吠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巩趁,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤痒玩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后议慰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蠢古,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年别凹,在試婚紗的時候發(fā)現(xiàn)自己被綠了草讶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡炉菲,死狀恐怖堕战,靈堂內(nèi)的尸體忽然破棺而出坤溃,到底是詐尸還是另有隱情,我是刑警寧澤嘱丢,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布浇雹,位于F島的核電站,受9級特大地震影響屿讽,放射性物質(zhì)發(fā)生泄漏昭灵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一伐谈、第九天 我趴在偏房一處隱蔽的房頂上張望烂完。 院中可真熱鬧,春花似錦诵棵、人聲如沸抠蚣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘶窄。三九已至,卻和暖如春距贷,著一層夾襖步出監(jiān)牢的瞬間柄冲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工忠蝗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留现横,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓阁最,卻偏偏與公主長得像戒祠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子速种,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò)特有的延遲以及數(shù)據(jù)傳輸?shù)某杀窘萍s互聯(lián)網(wǎng)快速獲取Web資源。為此配阵,HTTP協(xié)議引入緩存以空間換時間馏颂,使瀏覽器緩...
    大頭8086閱讀 3,066評論 2 12
  • 今天看奇舞團推了篇文章講緩存策略的,講的挺不錯闸餐,記錄一下饱亮。 原文地址就在下面矾芙。 總結(jié): 緩存分為強緩存和協(xié)商緩存...
    NowhereToRun閱讀 4,816評論 1 7
  • 本文內(nèi)容大多參考《圖解HTTP》一書 一. 認識代理服務(wù)器 所以講緩存為什么要先扯代理服務(wù)器舍沙?別急,讓我們看一下一...
    流光號船長閱讀 1,921評論 0 10
  • 轉(zhuǎn)載:瀏覽器緩存知識小結(jié)及應(yīng)用 閱讀目錄 1. 瀏覽器緩存基本認識 2. 強緩存的原理 3. 強緩存的管理 4. ...
    meng_philip123閱讀 1,089評論 4 18
  • 瀏覽器對于請求資源, 流程如圖所示: 可以看到瀏覽器的緩存機制分為兩個部分: 1剔宪、當前緩存是否過期拂铡? 2壹无、服務(wù)器中...
    zhoulujun閱讀 1,200評論 0 3