瀏覽器緩存篇

前言

在前端開(kāi)發(fā)中褥影,緩存有利于加快網(wǎng)頁(yè)的加載速度哑芹,同時(shí)緩存能夠被反復(fù)利用,所以可以減少流量和帶寬的開(kāi)銷(xiāo)。

緩存的分類(lèi)有很多種耸成,CDN緩存、數(shù)據(jù)庫(kù)緩存羹唠、代理服務(wù)器緩存和瀏覽器緩存志鹃。本篇將來(lái)講解一下Web開(kāi)發(fā)中的瀏覽器緩存。這個(gè)在實(shí)際開(kāi)發(fā)環(huán)境中往往也會(huì)被問(wèn)到信轿,或者使用到晃痴。如何去準(zhǔn)確認(rèn)清楚緩存的概念,是前端必須要去學(xué)習(xí)的财忽。如果你喜歡我的文章倘核,歡迎評(píng)論,歡迎Star~定罢。歡迎關(guān)注我的github博客

正文

瀏覽器的緩存問(wèn)題笤虫,主要指的是http的緩存——即協(xié)議層。而h5新增的storage和數(shù)據(jù)庫(kù)緩存祖凫,那是應(yīng)用層緩存琼蚯,并不被計(jì)入本篇的分析內(nèi)容里面。下面我們正式開(kāi)始來(lái)進(jìn)行緩存的分析惠况。

協(xié)議層的緩存遭庶,其實(shí),可以被分成強(qiáng)制緩存和對(duì)比緩存稠屠。

強(qiáng)制緩存

首先峦睡,我們先來(lái)看一張強(qiáng)制緩存時(shí)的時(shí)序圖翎苫,來(lái)了解一下強(qiáng)制緩存在不同情況下的請(qǐng)求模式:

force cache

從圖中,我們不難看出榨了,只有當(dāng)緩存失效時(shí)煎谍,才會(huì)去服務(wù)器獲取最新資源的方式,就是強(qiáng)制緩存龙屉。而在協(xié)議層的字段中呐粘,可以造成強(qiáng)制緩存的字段有兩個(gè)Expires和Cache-Control。

1.0的時(shí)候見(jiàn)到我——Expires

最早使用的是Expires字段转捕,該字段表示緩存到期時(shí)間作岖,即有效時(shí)間+當(dāng)時(shí)服務(wù)器的時(shí)間,然后將這個(gè)時(shí)間設(shè)置在header中返回給服務(wù)器五芝。因此痘儡,該時(shí)間是一個(gè)絕對(duì)時(shí)間,舉例說(shuō)明:

Expires: Thu, 10 Nov 2017 08:45:11 GMT

圖片示例:

expires
expires

在響應(yīng)消息頭中枢步,設(shè)置這個(gè)字段之后沉删,就可以告訴瀏覽器,在未過(guò)期之前不需要再次請(qǐng)求价捧。

但是丑念,這個(gè)字段設(shè)置時(shí)有缺點(diǎn)

由于是絕對(duì)時(shí)間,用戶(hù)可能會(huì)將客戶(hù)端本地的時(shí)間進(jìn)行修改结蟋,而導(dǎo)致瀏覽器判斷緩存失效脯倚,重新請(qǐng)求該資源,同時(shí)嵌屎,還導(dǎo)致客戶(hù)端與服務(wù)端的時(shí)間不一致推正,致使緩存失效。

1.1的時(shí)候我來(lái)了——Cache-Control

已知Expires的缺點(diǎn)之后宝惰,在HTTP/1.1中植榕,增加了一個(gè)字段Cache-Control,該字段表示資源緩存的最大有效時(shí)間尼夺,在該時(shí)間內(nèi)尊残,客戶(hù)端不需要向服務(wù)器發(fā)送請(qǐng)求

這兩者的區(qū)別就是前者是絕對(duì)時(shí)間,而后者是相對(duì)時(shí)間淤堵。我們不妨舉個(gè)例子來(lái)說(shuō)明一下:

Cache-Control: max-age=2592000

圖片示例:

Cache-Control

下面列舉一下Cache-Control的字段可以帶的值:

  1. max-age:即最大有效時(shí)間寝衫,在上面的例子中我們可以看到

  2. no-cache:表示必須先與服務(wù)器確認(rèn)資源是否被更改過(guò)(依據(jù)If-None-Match和Etag),然后再?zèng)Q定是否使用本地緩存

  3. s-maxage:同max-age拐邪,但是僅用于共享緩存慰毅,如CDN緩存

  4. public:多用戶(hù)共享緩存,默認(rèn)設(shè)置

  5. private:不能夠多用戶(hù)共享扎阶,HTTP認(rèn)證之后汹胃,字段會(huì)自動(dòng)轉(zhuǎn)換成private婶芭。

總結(jié)一下,自從http1.1開(kāi)始着饥,Expires逐漸被Cache-Control取代犀农。Cache-Control是一個(gè)相對(duì)時(shí)間,即使客戶(hù)端時(shí)間發(fā)生改變宰掉,相對(duì)時(shí)間也不會(huì)隨之改變井赌,這樣可以保持服務(wù)器和客戶(hù)端的時(shí)間一致性。而且Cache-Control的可配置性比較強(qiáng)大贵扰。

對(duì)比緩存

扯完強(qiáng)制緩存,我們來(lái)看看對(duì)比緩存流部。在解釋這個(gè)之前戚绕,是否可以先猜想一下,強(qiáng)制緩存是枝冀,緩存在未過(guò)有效期時(shí)舞丛,不需要請(qǐng)求資源。那么果漾,對(duì)比緩存的原理又該如何呢球切?

廢話(huà)不多說(shuō),我們也先從對(duì)比緩存的時(shí)序圖講起绒障,如圖:

compare cache

對(duì)比緩存的過(guò)程是吨凑,先從緩存中獲取對(duì)應(yīng)的數(shù)據(jù)標(biāo)識(shí),然后向服務(wù)器發(fā)送請(qǐng)求户辱,確認(rèn)數(shù)據(jù)是否更新鸵钝,如果更新,則返回新數(shù)據(jù)和新緩存庐镐;反之恩商,則返回304狀態(tài)碼,告知客戶(hù)端緩存未更新必逆,可繼續(xù)使用怠堪。

這正好彌補(bǔ)了一些強(qiáng)制緩存的缺陷。對(duì)比緩存主要應(yīng)用于一些時(shí)常需要?jiǎng)討B(tài)更新的資源文件名眉。

對(duì)比緩存在協(xié)議里的字段是Last-Modified和If-Modified-Since粟矿。

別人的好伙伴——Last-Modified

Last-Modified:服務(wù)器告知客戶(hù)端,資源最后一次被修改的時(shí)間璧针,例如

Last-Modified: Thu, 10 Nov 2015 08:45:11 GMT
last-modified

If-Modified-Since:再次請(qǐng)求時(shí)嚷炉,請(qǐng)求頭中帶有該字段,服務(wù)器會(huì)將If-Modified-Since的值與Last-Modified字段進(jìn)行對(duì)比探橱,如果相等申屹,則表示未修改绘证,響應(yīng)304;反之哗讥,則表示修改了嚷那,響應(yīng)200狀態(tài)碼,返回?cái)?shù)據(jù)杆煞。

這個(gè)字段可以和Cache-Control配合使用魏宽。

但是他還是有一定缺陷的:

  1. 如果資源更新的速度是秒以下單位,那么該緩存是不能被使用的决乎,因?yàn)樗臅r(shí)間單位最低是秒队询。

  2. 如果文件是通過(guò)服務(wù)器動(dòng)態(tài)生成的,那么該方法的更新時(shí)間永遠(yuǎn)是生成的時(shí)間构诚,盡管文件可能沒(méi)有變化蚌斩,所以起不到緩存的作用。

我來(lái)完善它——Etag

由于Last-modified還是存在缺陷的范嘱,盡管大多數(shù)情況下送膳,會(huì)使用它,但當(dāng)遇到我們上面所說(shuō)的場(chǎng)景時(shí)丑蛤,我們可能就需要了解一下叠聋,我們另一個(gè)小伙伴了——Etag。

Etag存儲(chǔ)的是文件的特殊標(biāo)識(shí)(一般都是hash生成的)受裹,服務(wù)器存儲(chǔ)著文件的Etag字段碌补,可以在與每次客戶(hù)端傳送If-no-match的字段進(jìn)行比較,如果相等名斟,則表示未修改脑慧,響應(yīng)304;反之砰盐,則表示已修改闷袒,響應(yīng)200狀態(tài)碼,返回?cái)?shù)據(jù)岩梳。

最后囊骤,通過(guò)一張?jiān)韴D,我們來(lái)加深一下記憶:

etag

至此為止冀值,兩種緩存類(lèi)型的緩存方式已經(jīng)闡述完成了也物,不知你是否已經(jīng)心中已經(jīng)有個(gè)大致的印象,當(dāng)別人問(wèn)起時(shí)列疗,你可以對(duì)答如流滑蚯。希望我們一同進(jìn)步吧,fighting。

瀏覽器行為引起的不同

最后告材,我們來(lái)聊聊瀏覽器行為會(huì)引起緩存的變化吧坤次。

下面說(shuō)一下瀏覽器的行為會(huì)產(chǎn)生怎樣的請(qǐng)求:

  1. 刷新網(wǎng)頁(yè) => 如果緩存沒(méi)有失效,瀏覽器會(huì)直接使用緩存斥赋;反之缰猴,則向服務(wù)器請(qǐng)求數(shù)據(jù)
  2. 手動(dòng)刷新(F5) => 瀏覽器會(huì)認(rèn)為緩存失效,在請(qǐng)求服務(wù)器時(shí)加上Cache-Control: max-age=0字段疤剑,然后詢(xún)問(wèn)服務(wù)器數(shù)據(jù)是否更新滑绒。
  3. 強(qiáng)制刷新(Ctrl + F5) => 瀏覽器會(huì)直接忽略緩存,在請(qǐng)求服務(wù)器時(shí)加上Cache-Control: no-cache字段隘膘,然后重新向服務(wù)器拉取文件疑故。

移動(dòng)端的緩存處理

在PC端或許這樣子的緩存機(jī)制就已經(jīng)足夠了,因?yàn)镻C端不需要為網(wǎng)絡(luò)的問(wèn)題擔(dān)心弯菊。

但是焰扳,移動(dòng)端卻不行,任何一個(gè)網(wǎng)絡(luò)請(qǐng)求的增加误续,對(duì)于移動(dòng)端的加載消耗時(shí)間都是比較大的(誰(shuí)叫移動(dòng)端的網(wǎng)太差呢,3G扫茅、2G)蹋嵌。那么,上述的緩存有什么問(wèn)題呢葫隙?其實(shí)栽烂,強(qiáng)制緩存是沒(méi)有太大問(wèn)題的,因?yàn)橹灰彺娌坏狡诹到牛遣粫?huì)想服務(wù)器發(fā)送請(qǐng)求的腺办;但是如果是對(duì)比緩存的情況下,304的問(wèn)題就比較巨大糟描,因?yàn)樗鼤?huì)造成無(wú)用的請(qǐng)求怀喉。每次在使用緩存前,都會(huì)向服務(wù)器發(fā)送請(qǐng)求確認(rèn)船响,導(dǎo)致網(wǎng)絡(luò)的延時(shí)躬拢。

一次完美的緩存必須保證兩點(diǎn):

  1. 數(shù)據(jù)緩存之后,盡量減少服務(wù)器的請(qǐng)求
  2. 如果資源更新的話(huà)见间,必須使得客戶(hù)端的資源一起更新聊闯。

所以,一般我們會(huì)運(yùn)用的方式是:

在資源文件后面加上表示米诉,如config.f1ec3.js菱蔬、config.v1.js之類(lèi)的,然后給資源設(shè)置較長(zhǎng)的緩存時(shí)間,如一年

Cache-Control: max-age=31536000

這樣子拴泌,就不會(huì)造成304的回包現(xiàn)象魏身。
然后一旦資源發(fā)生更新時(shí),我們可以改變資源后面的標(biāo)識(shí)符弛针,實(shí)現(xiàn)靜態(tài)資源非覆蓋式更新叠骑。

總結(jié)

本篇大致分析了瀏覽器緩存部分的分類(lèi)情況,以及細(xì)化分析削茁。主要可分為:

  1. 強(qiáng)制緩存

    • Expires字段

    • Cache-Control字段

  2. 對(duì)比緩存

    • Last-Modefied字段

    • Etag標(biāo)識(shí)

  3. 瀏覽器行為引起的緩存變化

  4. 移動(dòng)端的緩存策略

其實(shí)宙枷,在講述移動(dòng)端的緩存策略時(shí),并沒(méi)有分析的特別詳細(xì)茧跋,只是大致的講解了一下目前大家都在使用的緩存策略慰丛。可能之后瘾杭,還會(huì)寫(xiě)一篇移動(dòng)端緩存的細(xì)分文章诅病。

最后,如果你對(duì)我寫(xiě)的有疑問(wèn)粥烁,可以與我討論贤笆。如果我寫(xiě)的有錯(cuò)誤,歡迎指正讨阻。你喜歡我的博客芥永,請(qǐng)給我關(guān)注Star~呦。大家一起總結(jié)一起進(jìn)步钝吮。歡迎關(guān)注我的github博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末埋涧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子奇瘦,更是在濱河造成了極大的恐慌棘催,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耳标,死亡現(xiàn)場(chǎng)離奇詭異醇坝,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)次坡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)纲仍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人贸毕,你說(shuō)我怎么就攤上這事郑叠。” “怎么了明棍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵乡革,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)沸版,這世上最難降的妖魔是什么嘁傀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮视粮,結(jié)果婚禮上细办,老公的妹妹穿的比我還像新娘。我一直安慰自己蕾殴,他們只是感情好笑撞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著钓觉,像睡著了一般茴肥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荡灾,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天瓤狐,我揣著相機(jī)與錄音,去河邊找鬼批幌。 笑死础锐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的荧缘。 我是一名探鬼主播郁稍,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼胜宇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起恢着,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤桐愉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后掰派,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體从诲,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年靡羡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了系洛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡略步,死狀恐怖描扯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情趟薄,我是刑警寧澤绽诚,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響恩够,放射性物質(zhì)發(fā)生泄漏卒落。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一蜂桶、第九天 我趴在偏房一處隱蔽的房頂上張望儡毕。 院中可真熱鬧,春花似錦扑媚、人聲如沸腰湾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)檐盟。三九已至,卻和暖如春押桃,著一層夾襖步出監(jiān)牢的瞬間葵萎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工唱凯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留羡忘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓磕昼,卻偏偏與公主長(zhǎng)得像卷雕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子票从,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

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