<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>

          你真的懂HTTP緩存嗎?

          共 5410字,需瀏覽 11分鐘

           ·

          2024-05-24 12:10

              

          作者:程序員小楊v1

          鏈接:https://juejin.cn/post/7281088405189427215

          背景

          需求開發(fā)中不斷的往項目中添加圖片、字體等這些靜態(tài)資源使得項目打包體積越來越大。

          打包后這些靜態(tài)資源占據(jù)了包體積的大部分。

          基于此,我們準(zhǔn)備將靜態(tài)資源從項目中移出來放到 oss 云服務(wù)上,這樣項目的體積會縮小很多,打包速度也會快很多

          但是,想法是好的,但是具體的操作上存在一些問題需要解決:

          • 靜態(tài)資源的緩存問題
          • 目錄結(jié)構(gòu)問題
          • 資源更新問題

          這篇文章我會重點分享靜態(tài)資源緩存問題的解決方案。

          HTTP 緩存

          說到靜態(tài)資源的緩存問題其實就是HTTP緩存的問題,我們既要保證客戶端能快速的加載靜態(tài)資源還需要保證當(dāng)靜態(tài)資源變化時,客戶端能及時更新。

          緩存過程

          image.png

          由上圖我們可以發(fā)現(xiàn):

          • 瀏覽器在請求資源時,都會去查看當(dāng)前瀏覽器緩存中是否存在緩存結(jié)果和緩存標(biāo)識
          • 當(dāng)請求結(jié)果返回瀏覽器時,瀏覽器都會將當(dāng)前結(jié)果和緩存標(biāo)識存入瀏覽器緩存中

          以上兩點是瀏覽器緩存機制的關(guān)鍵,它確保了每個請求的緩存存入與讀取。

          根據(jù)是否需要向服務(wù)器重新發(fā)起 HTTP 請求將緩存過程分為兩個部分,分別是強緩存和協(xié)商緩存。

          強緩存

          強緩存,顧名思義就是強制緩存,是不需要向原服務(wù)器發(fā)起請求直接使用瀏覽器緩存

          強緩存的實現(xiàn)方案主要是有兩種:Expirescache-control

          • Expires:過期時間,如果設(shè)置了過期時間,則瀏覽器會在過期時間內(nèi)使用緩存。Expires 是 HTTP1.0 的產(chǎn)物,受限于本地時間,如果人為修改了本地時間,可能會造成緩存失效。

          • cache-control:緩存控制,常用有以下幾個設(shè)置:

            • max-age:表示緩存可以使用多長時間,是一個相對時間
            • public:表示響應(yīng)可以被任何區(qū)緩存
            • private:只針對個人用戶,不可被代理服務(wù)器緩存
            • no-cache:可以在本地緩存,可以在代理服務(wù)器緩存,但是這個緩存要服務(wù)器驗證才可以使用,強制客戶端總是向服務(wù)器發(fā)送請求,由服務(wù)器判斷緩存是否可用,即總是啟用協(xié)商緩存
            • no-store:徹底禁用緩存,每次都需要從服務(wù)器獲取資源,流量消耗增加

          Expirescache-control 都可以實現(xiàn)強緩存

          資源在 2023 年 2 月 28 號 22:22:22 過期

          Expires: Tue, 28 Feb 2023 22:22:22 GMT

          資源在1小時內(nèi)可使用緩存

          Date: Tue, 22 Feb 2022 22:22:22 GMT
          Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT
          Cache-Control: max-age=3600

          但是Expires 是http1.0的產(chǎn)物,cache-control是http1.1的產(chǎn)物,現(xiàn)階段,我們會認(rèn)為cache-control使用更廣泛,Expires只是一種降級方案。

          當(dāng)Expirescache-control同時存在時,瀏覽器會優(yōu)先使用cache-control

          協(xié)商緩存

          • Etag/If-None-Match

            • Etag:這個字段是由服務(wù)器生成返回給瀏覽器的,它的值是由文件的索引節(jié)點(INode)、文件大小(size)、文件最后修改時間(MTime)進(jìn)行hash之后得到的
            • If-None-Match:再次請求該資源時,帶上上一次服務(wù)器返回的ETag

          過程:當(dāng)強緩存過期,瀏覽器會啟用協(xié)商緩存,首先判斷當(dāng)前是否存在ETag,如果存在,則再次向服務(wù)器發(fā)送請求時,在請求頭上加上If-None-Match一同發(fā)送到服務(wù)器,服務(wù)器比對當(dāng)前的If-None-Match與資源相對應(yīng)的ETag是否相同,如果相同則說明緩存可用,則返回304,否則返回最新的資源。

          • Last-Modified/If-Modified-Since

            • Last-Modified:服務(wù)器返回的文件最后修改時間
            • If-Modified-Since:再次請求資源是,帶上上一次服務(wù)器返回的Last-Modified

          過程:當(dāng)資源過期時,如果不存在ETag而是存在Last-modified,則再次向服務(wù)器發(fā)送請求時,在請求頭上會帶上If-Modified-Since一同發(fā)送給服務(wù)器,服務(wù)器對比資源最后修改時間和當(dāng)前客戶端發(fā)送的If-Modified-Since這個時間,判斷資源是否被修改,如果修改了則返回最新的資源,如果沒有修改則返回304,使用緩存。微信搜索公眾號:架構(gòu)師指南,回復(fù):架構(gòu)師 領(lǐng)取資料 。

          ETag的優(yōu)先級高于Last-Modified,服務(wù)器會優(yōu)先驗證ETag

          Last-Modified是以秒為單位的,所以在資源頻繁更改的情況下,Last-Modified是不安全的,而ETag可以檢查文件大小和文件的唯一索引節(jié)點,故即使修改頻繁的資源依然能檢測到更改

          緩存策略

          基于上面介紹的強緩存和協(xié)商緩存特點,以下是筆者總結(jié)的緩存策略;

          頻繁變動的資源

          對于頻繁變動的資源,肯定首先要保證的就是及時性,即服務(wù)器文件更新,需要盡快展示在客戶端,所以對于此種資源,建議禁用強制緩存,采用協(xié)商緩存的策略。

          cache-control: no-cache
          Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT
          ETag: deadbeef

          以上標(biāo)識中

          • cache-control: no-cache ,表示每次都從服務(wù)器詢問資源是否更改
          • Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT, 表示資源的最后修改時間
          • ETag: deadbeef ,表示資源對應(yīng)的唯一標(biāo)識

          過程如下:

          1. 當(dāng)瀏覽器查發(fā)現(xiàn)cache-control: no-cache 時,會向服務(wù)器發(fā)起該資源的請求

          2. 但是在請求前,瀏覽器會先在自己的緩存中查找該資源, 如果發(fā)現(xiàn)存在該資源的緩存文件,則將該緩存文件的EtagLast-Modified字段轉(zhuǎn)換為請求頭中的If-None-MatchIf-Modified-Since一同發(fā)送到服務(wù)端

          3. 如果發(fā)現(xiàn)不存在該資源,則直接請求

          4. 服務(wù)器接收到資源請求,如果不存在If-None-MatchIf-Modified-Since請求頭,則說明客戶端沒有緩存,直接返回資源

          5. 如果存在If-None-MatchIf-Modified-Since請求頭,服務(wù)器比對當(dāng)前的If-None-Match與資源相對應(yīng)的ETag是否相同,如果相同則說明文件沒有更改,返回304讓瀏覽器使用緩存,如果不相同,返回新文件。

          不經(jīng)常變化的資源

          對于不經(jīng)常變化的資源,建議設(shè)置強緩存,

          cache-control:max-age=31536000

          如上設(shè)置會強緩存該資源一年時間,如果我們中間需要修改該資源,可以采用在資源鏈接末尾添加唯一hash或是唯一時間戳來解決。

          加餐

          對于需要緩存的文件,建議明確指出cache-control字段,如果沒有設(shè)置該字段,則瀏覽器會采用一種叫做啟發(fā)式緩存的方式緩存文件。

          HTTP/1.1 200 OK
          Content-Type: text/html
          Content-Length: 1024
          Date: Tue, 22 Feb 2022 22:22:22 GMT
          Last-Modified: Tue, 22 Feb 2021 22:22:22 GMT

          如果存在以上響應(yīng),不存在cache-control字段

          試探性地知道,整整一年沒有更新的內(nèi)容在那之后的一段時間內(nèi)不會更新。

          因此,客戶端存儲此響應(yīng)(盡管缺少 max-age)并重用它一段時間。

          復(fù)用多長時間取決于實現(xiàn),但規(guī)范建議存儲后大約 10%(在本例中為 0.1 年)的時間。

          由此可見,如果不指明cache-control字段會導(dǎo)致不必要的緩存,或是無謂的流量消耗。

          所以,建議所有靜態(tài)資源都明確指出cache-control字段,明確緩存策略。

               
                  

          —  —

                        
          關(guān)注公眾號后,回復(fù)下面關(guān)鍵詞獲取
          回復(fù) 加群,加入前端程序員技術(shù)交流群

                  
                        
          回復(fù) 面試,獲取最新大廠面試資料
          回復(fù) 簡歷,獲取 3200 套 簡歷模板
          回復(fù) TypeScript,獲取 TypeScript 精講課程
          回復(fù) uniapp,獲取 uniapp 精講課程
          回復(fù) Node,獲取 Nodejs+koa2 實戰(zhàn)教程
          回復(fù) 架構(gòu)師,獲取 架構(gòu)師學(xué)習(xí)資源教程
                  
                        
          更多教程資源應(yīng)用盡有,歡迎 關(guān)注獲取


             “分享、點贊在看” 支持一波??


          瀏覽 94
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  九九九九九九九九九九九精品 | 成人毛片在线 | 色老扳AV | 91av-91av在线盒子 | 一本大道久久人妻无码 |