<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          動(dòng)畫:深入淺出從根上理解 HTTP 緩存機(jī)制及原理!

          共 3298字,需瀏覽 7分鐘

           ·

          2020-08-04 20:36

          HTTP 緩存,對(duì)于前端的性能優(yōu)化方面來講,是非常關(guān)鍵的,從緩存中讀取數(shù)據(jù)和直接向服務(wù)器請(qǐng)求數(shù)據(jù),完全就是一個(gè)在天上,一個(gè)在地下。


          我們最熟悉的是 HTTP 服務(wù)器響應(yīng)返回狀態(tài)碼 304,304 代表表示告訴瀏覽器,本地有緩存數(shù)據(jù),可直接從本地獲取,無需從服務(wù)器獲取浪費(fèi)時(shí)間。


          至于為什么被緩存,如何命中緩存以及緩存什么時(shí)候生效的,我們卻很少在實(shí)際開發(fā)中去了解。今天小鹿借助動(dòng)畫形式來從根上理解 HTTP 緩存機(jī)制及原理。


          為什么會(huì)有緩存?



          單純的從計(jì)算機(jī)角度去說,比較抽象,咱們看一個(gè)實(shí)際的例子。比如,我們通常喜歡把沒看完的書放在書架上,而看完以及沒有看的書放在箱子中保存。


          如果我們把所有的書保存在箱子中,每次看書都要去箱子中找,所以非常麻煩和耗時(shí)(這里的箱子,可以想象成服務(wù)器)。


          當(dāng)我們開始看新書時(shí),第一次從箱子中取出,看了一半,然后我們直接放到書架上,當(dāng)下次再看書的時(shí)候,直接從書架中取出,這里的書架,就是我們下邊要講到的緩存(一個(gè)緩存?zhèn)}庫(kù))。


          緩存的“龜”則



          當(dāng)瀏覽器發(fā)出請(qǐng)求到數(shù)據(jù)請(qǐng)求回來的過程,就像是上述中的取書過程。


          瀏覽器在加載資源時(shí),根據(jù)請(qǐng)求頭的Expires 和 Cache-control 判斷是否命中強(qiáng)緩存,是則直接從緩存讀取資源,不會(huì)發(fā)請(qǐng)求到服務(wù)器。


          如果沒有命中強(qiáng)緩存,瀏覽器一定會(huì)發(fā)送一個(gè)請(qǐng)求到服務(wù)器,通過 Last-Modified 和 Etag 驗(yàn)證資源是否命中協(xié)商緩存,如果命中,服務(wù)器會(huì)將這個(gè)請(qǐng)求返回,但是不會(huì)返回這個(gè)資源的數(shù)據(jù),依然是從緩存中讀取資源。


          如果前面兩者都沒有命中,直接從服務(wù)器加載資源。


          動(dòng)畫演示




          HTTP 緩存分類



          上述講到,HTTP 是有“龜”則的,根據(jù)瀏覽器是否向服務(wù)器發(fā)起請(qǐng)求來分為強(qiáng)緩存和協(xié)商緩存


          1、強(qiáng)緩存


          強(qiáng)緩存的意思就是不向服務(wù)器發(fā)起請(qǐng)求的緩存,也就是本地強(qiáng)制緩存。瀏覽器想要獲取特定數(shù)據(jù)的時(shí)候,首先會(huì)檢查一下本地的緩存是否存在該數(shù)據(jù),如果存在,就直接在本地獲取了,如果不存在,就向服務(wù)器所要該數(shù)據(jù)。


          詳細(xì)請(qǐng)求過程如下動(dòng)畫所示:





          那么問題來了,如果我們想使用強(qiáng)緩存,那怎么判斷緩存數(shù)據(jù)什么時(shí)候失效呢?


          當(dāng)瀏覽器向服務(wù)器請(qǐng)求數(shù)據(jù)的時(shí)候,服務(wù)器會(huì)將數(shù)據(jù)和緩存的規(guī)則返回,在響應(yīng)頭的 header 中,有兩個(gè)字段 Expires和Cache-Control。


          Expires


          1expires:?Wed,?11?Sep?2019?16:12:18?GMT


          在響應(yīng)頭中 Expires 字段的意思是,當(dāng)前返回?cái)?shù)據(jù)的緩存到期時(shí)間戳。當(dāng)瀏覽器在進(jìn)行請(qǐng)求的時(shí)候,會(huì)那瀏覽器本地的時(shí)候和這個(gè)時(shí)間做對(duì)比,判斷資源是否過期。


          但是上述存在一個(gè)問題就是,如果我手動(dòng)改變了電腦的時(shí)間,那么就會(huì)出現(xiàn)問題,這也是 HTTP1.0 中存在的問題。


          Cache-Control


          為了解決這個(gè)問題,在 HTTP1.1 中增加了 Cache-Control 這個(gè)字段。


          1Cache-Control:max-age=7200


          服務(wù)器和客戶端說,這個(gè)資源緩存只可以存在 7200 秒,在這個(gè)時(shí)間段之內(nèi),你就可以在緩存獲取資源。


          如果 Expire 和 Cache-control 兩者同時(shí)出現(xiàn),則以 Cache-control 為主


          除此之外,cache-control 還有其他字段可以使用。


          1cache-control:?max-age=3600,?s-maxage=31536000


          • Public:只要為資源設(shè)置了 public,那么它既可以被瀏覽器緩存,也可以被代理服務(wù)器緩存;

          • Private(默認(rèn)值):則該資源只能被瀏覽器緩存。

          • no-store:不使用任何緩存,直接向服務(wù)器發(fā)起請(qǐng)求。

          • no-cache:繞開瀏覽器緩存(每次發(fā)起請(qǐng)求不會(huì)詢問瀏覽器緩存),而是直接向服務(wù)器確認(rèn)該緩存是夠過期。


          2、協(xié)商緩存


          瀏覽器第一次請(qǐng)求數(shù)據(jù)時(shí),服務(wù)器會(huì)將緩存標(biāo)識(shí)與數(shù)據(jù)一起返回給客戶端,客戶端將二者備份至緩存數(shù)據(jù)庫(kù)中。


          再次請(qǐng)求數(shù)據(jù)時(shí),客戶端將備份的緩存標(biāo)識(shí)發(fā)送給服務(wù)器,服務(wù)器根據(jù)緩存標(biāo)識(shí)進(jìn)行判斷,判斷成功后,返回304狀態(tài)碼,通知客戶端比較成功,可以使用緩存數(shù)據(jù)。




          1//?命中緩存的響應(yīng)字段
          2Request?Method:GET
          3Status?Code:?304?Not?Modified


          怎么來識(shí)別協(xié)商緩存的?主要通過報(bào)文頭部 header 中的Last-Modified,If-Modified-Since 以及ETag、If-None-Match 字段來進(jìn)行識(shí)別。


          Last-Modified?


          Last-Modified 字段的意思是服務(wù)器資源的最后修改時(shí)間。第一次請(qǐng)求服務(wù)器,服務(wù)器的頭部字段可增加這個(gè)字段,用于設(shè)置協(xié)商緩存。


          1Last-Modified:?Fri,?27?Oct?2017?06:35:57?GMT


          當(dāng)瀏覽器再次發(fā)起請(qǐng)求的時(shí)候,首部字段增加 If-Modified-Since 本地時(shí)間戳字段發(fā)給服務(wù)器。


          1If-Modified-Since:?Fri,?27?Oct?2017?06:35:57?GMT


          服務(wù)端接收到請(qǐng)求之后,就拿 If-Modified-Since 字段值和本身的過期時(shí)間對(duì)比。


          如果請(qǐng)求頭中的這個(gè)值小于最后修改時(shí)間,返回的 304 響應(yīng),讓其在本地瀏覽器緩存取出數(shù)據(jù)。如果時(shí)間過期,并在 Response Headers中添加新的 Last-Modified 值返回給瀏覽器。


          但是 Last-Modified 存在一個(gè)局限性,有以下兩種情況:


          不該請(qǐng)求,還會(huì)請(qǐng)求。編輯了文件,文件內(nèi)容沒有變,但是服務(wù)器確認(rèn)為我們改動(dòng)了文件,所以重新設(shè)置了緩存時(shí)間,當(dāng)做新請(qǐng)求返回給瀏覽器。


          該請(qǐng)求,反而沒有請(qǐng)求。修改文件速度很快,快過 If-Modified-Since 字段時(shí)間差的檢測(cè),文件雖然改動(dòng)了,但是并沒有重新生成新的資源。


          ETag


          ETag 代表的意思是標(biāo)識(shí)字符串。由于上述 Last-Modified 字段存在的缺陷,所以在 HTTP / 1.1 ?我們對(duì)資源進(jìn)行內(nèi)容編碼,只要內(nèi)容被改變,這個(gè)編碼就不同。


          和上述請(qǐng)求原理一樣,瀏覽器首次發(fā)起請(qǐng)求,然后服務(wù)器在響應(yīng)頭返回一個(gè)標(biāo)識(shí)字符串。


          1ETag:?W/"2a3b-1602480f459"


          瀏覽器再次發(fā)起請(qǐng)求,攜帶一個(gè)值相同的字符串。


          1If-None-Match:?W/"2a3b-1602480f459"


          服務(wù)端接收到該字符串就會(huì)作對(duì)比,如果相同,則讓其讀取本地緩存,否則,將新的資源返回給瀏覽器端。


          緩存位置



          緩存的位置按照獲取資源請(qǐng)求優(yōu)先級(jí),緩存位置依次如下:


          • Memory Cache(內(nèi)存緩存)

          • Service Worker(離線緩存)

          • Disk Cache(磁盤緩存)

          • Push Cache(推送緩存)


          Memory Cache


          Memory 為內(nèi)存緩存,是瀏覽器最先嘗試命中的緩存,也是響應(yīng)最快的緩存。但是存活時(shí)間最短的,當(dāng)進(jìn)程結(jié)束后,tab 標(biāo)簽關(guān)閉后,緩存就不存在了。



          因?yàn)閮?nèi)存空間比較小,通常較小的資源放在內(nèi)存緩存中,比如 base64 圖片等資源。


          Service Worker


          Service Worker 是一種獨(dú)立于主線程之外的 Javascript 線程。它脫離于瀏覽器窗體,因此無法直接訪問 DOM。


          可以幫我們實(shí)現(xiàn)離線緩存、消息推送和網(wǎng)絡(luò)代理等功能。


          Disk Cache


          內(nèi)存的優(yōu)先性,導(dǎo)致大文件不能緩存到內(nèi)存中,那么磁盤緩存則不同。雖然存儲(chǔ)效率比內(nèi)存緩存慢,但是存儲(chǔ)容量和存儲(chǔ)市場(chǎng)有優(yōu)勢(shì)。


          Push Cache


          它是最后一道緩存命中,屬于 HTTP2 的內(nèi)容。如果感興趣的同學(xué),可以先去了解了解。


          -------------------------





          推薦閱讀




          我的公眾號(hào)能帶來什么價(jià)值?(文末有送書規(guī)則,一定要看)

          每個(gè)前端工程師都應(yīng)該了解的圖片知識(shí)(長(zhǎng)文建議收藏)

          為什么現(xiàn)在面試總是面試造火箭?

          瀏覽 72
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色免费a一片 | 高h视频在线观看 | 成人在线18禁 | 免费无码婬片AAAA片直播 | 国产高清性 |