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

          學(xué)會(huì)這篇就夠了,徹底弄懂前端緩存

          共 5406字,需瀏覽 11分鐘

           ·

          2022-02-15 08:36

          點(diǎn)擊上方 前端瓶子君,關(guān)注公眾號(hào)

          回復(fù)算法,加入前端編程面試算法每日一題群

          前端緩存

          前端緩存,這是一個(gè)老生常談的話題,也常被作為前端面試的一個(gè)知識(shí)點(diǎn)。今天我們?cè)賮砜偨Y(jié)一下。

          分類

          前端緩存分為強(qiáng)緩存和協(xié)商緩存兩種。

          強(qiáng)緩存

          強(qiáng)緩存主要使用Expires、Cache-Control 兩個(gè)頭字段,兩者同時(shí)存在Cache-Control 優(yōu)先級(jí)更高。當(dāng)命中強(qiáng)緩存的時(shí)候,客戶端不會(huì)再求,直接從緩存中讀取內(nèi)容,并返回HTTP狀態(tài)碼200。

          • Expires

          響應(yīng)頭,代表該資源的過期時(shí)間。是一個(gè)GMT 格式的標(biāo)準(zhǔn)時(shí)間。

          當(dāng)客戶端請(qǐng)求服務(wù)器的時(shí)候,服務(wù)器會(huì)返回資源的同時(shí)還會(huì)帶上響應(yīng)頭Expires,表示資源的過期具體時(shí)間,如果客戶端在過期時(shí)間之前再次獲取該資源,就不需要再請(qǐng)求我服務(wù)器了,可以直接在緩存里面拿。

          使用Expires強(qiáng)緩存優(yōu)點(diǎn):

          • 在過期時(shí)間以內(nèi),為用戶省了很多流量。
          • 減少了服務(wù)器重復(fù)讀取磁盤文件的壓力。

          使用Expires強(qiáng)緩存缺點(diǎn)

          • 緩存過期以后,服務(wù)器不管文件有沒有變化會(huì)再次請(qǐng)求服務(wù)器。

          • 緩存過期時(shí)間是一個(gè)具體的時(shí)間,這個(gè)時(shí)間依賴于客戶端的時(shí)間,如果時(shí)間不準(zhǔn)確或者被改動(dòng)緩存也會(huì)隨之受到影響。

          • Cache-Control

          請(qǐng)求/響應(yīng)頭,緩存控制字段,精確控制緩存策略。

          為了讓強(qiáng)緩存更精確,HTTP1.1增加了Cache-Control字段。Cache-Control既能出現(xiàn)在請(qǐng)求頭又能出現(xiàn)在響應(yīng)頭,其不同的值代表不同的意思,下面我們具體分析一下。

          Cache-Control 服務(wù)端參數(shù):

          • max-age: 在多少秒內(nèi)有效,是一個(gè)相對(duì)時(shí)間,這樣比Expires具體的時(shí)間就更精確了。
          • s-maxage: 就是用于表示 cache 服務(wù)器上(比如 cache CDN,緩存代理服務(wù)器)的緩存的有效時(shí)間的,并只對(duì) public 緩存有效。
          • no-cache:不使用本地強(qiáng)緩存。需要使用緩存協(xié)商。
          • no-store:直接禁止瀏覽器緩存數(shù)據(jù),每次用戶請(qǐng)求該資源,都會(huì)向服務(wù)器發(fā)送一個(gè)請(qǐng)求,每次都會(huì)下載完整的資源。
          • public:可以被所有的用戶緩存,包括終端用戶和中間代理服務(wù)器。
          • private:只能被終端用戶的瀏覽器緩存,不允許中間緩存代理進(jìn)行緩存,默認(rèn)的。

          Cache-Control 客戶端參數(shù):

          • max-stale: 5 表示客戶端到代理服務(wù)器上拿緩存的時(shí)候,即使代理緩存過期了也不要緊,只要過期時(shí)間在 5 秒之內(nèi),還是可以從代理中獲取的。
          • min-fresh: 5 表示代理緩存需要一定的新鮮度,不要等到緩存剛好到期再拿,一定要在到期前 5 秒之前的時(shí)間拿,否則拿不到。
          • only-if-cached 這個(gè)字段加上后表示客戶端只會(huì)接受代理緩存,而不會(huì)接受源服務(wù)器的響應(yīng)。如果代理緩存無效,則直接返回 504(Gateway Timeout)。

          協(xié)商緩存

          協(xié)商緩存主要有四個(gè)頭字段,它們兩兩組合配合使用,If-Modified-Since 和 Last-Modified一組,Etag 和 If-None-Match一組,當(dāng)同時(shí)存在的時(shí)候會(huì)以Etag 和 If-None-Match為主。當(dāng)命中協(xié)商緩存的時(shí)候,服務(wù)器會(huì)返回HTTP狀態(tài)碼304,讓客戶端直接從本地緩存里面讀取文件。

          • If-Modified-Since

          請(qǐng)求頭,資源最近修改時(shí)間,由瀏覽器告訴服務(wù)器。其實(shí)就是第一次訪問服務(wù)端返回的Last-Modified的值。

          • Last-Modified

          響應(yīng)頭,資源最近修改時(shí)間,由服務(wù)器告訴瀏覽器。

          • Etag

          響應(yīng)頭,資源標(biāo)識(shí),由服務(wù)器告訴瀏覽器。

          • If-None-Match

          請(qǐng)求頭,緩存資源標(biāo)識(shí),由瀏覽器告訴服務(wù)器。其實(shí)就是第一次訪問服務(wù)端返回的Etag的值。

          If-Modified-Since 和 Last-Modified

          當(dāng)客戶端第一次請(qǐng)求服務(wù)器的時(shí)候,服務(wù)端會(huì)返回一個(gè)Last-Modified響應(yīng)頭,該字段是一個(gè)標(biāo)準(zhǔn)時(shí)間。客戶端請(qǐng)求服務(wù)器的時(shí)候會(huì)帶上If-Modified-Since請(qǐng)求頭字段,該字段的值就是服務(wù)器返回的Last-Modified的值。服務(wù)器接收到請(qǐng)求后會(huì)比較這兩個(gè)值是否一樣,一樣就返回304,讓客戶端從緩存中讀取,不一樣就會(huì)返回新文件給客戶端并更新Last-Modified響應(yīng)頭字段的值。

          使用If-Modified-Since 和 Last-Modified的優(yōu)點(diǎn):

          • 當(dāng)緩存有效時(shí)服務(wù)器不會(huì)返回文件給客戶端,而是直接返回304狀態(tài)碼,讓客戶端從緩存中獲取文件。大大節(jié)省了流量和帶寬以及服務(wù)器的壓力。

          使用If-Modified-Since 和 Last-Modified的缺點(diǎn):

          • Last-Modified 過期時(shí)間只能精確到秒。如果在同一秒既修改了文件又獲取文件,客戶端是獲取不到最新文件的。

          Etag 和 If-None-Match

          為了解決文件修改時(shí)間只能精確到秒帶來的問題,我們引入 Etag 響應(yīng)頭。Etag 是由文件修改時(shí)間與文件大小計(jì)算而成,只有當(dāng)文件文件內(nèi)容或修改時(shí)間變了Etag的值才會(huì)發(fā)生變化。

          當(dāng)客戶端第一次請(qǐng)求服務(wù)器的時(shí)候,服務(wù)端會(huì)返回一個(gè)Etag響應(yīng)頭。客戶端請(qǐng)求服務(wù)器的時(shí)候會(huì)帶上If-None-Match請(qǐng)求頭字段,該字段的值就是服務(wù)器返回的Etag的值。服務(wù)器接收到請(qǐng)求后會(huì)比較這兩個(gè)值是否一樣,一樣就返回304,讓客戶端從緩存中讀取,不一樣就會(huì)返回新文件給客戶端并更新Etag響應(yīng)頭字段的值。

          使用Etag 和 If-None-Match的優(yōu)點(diǎn):

          • 當(dāng)緩存有效時(shí)服務(wù)器不會(huì)返回文件給客戶端,而是直接返回304狀態(tài)碼,讓客戶端從緩存中獲取文件。大大節(jié)省了流量和帶寬以及服務(wù)器的壓力。
          • 并且解決了一秒內(nèi)修改并讀取的問題。

          擴(kuò)展

          緩存失效問題

          引入了緩存固然是好事,能大大提升響應(yīng)速度以及減輕服務(wù)端的壓力,但是也會(huì)出現(xiàn)一些問題,比如我們明明更新了系統(tǒng)版本,為什么客戶端看到的還是老文件。在不同的時(shí)代有不同的解決方案。

          老方案

          老方案通過人工自己修改文件名或者在文件名后帶上版本號(hào)、時(shí)間戳,這樣客戶端就會(huì)當(dāng)新文件請(qǐng)求并使用,之前的強(qiáng)緩存就算在有效期內(nèi)也會(huì)失效。

          <script src="http://randy.js?version=1.1.1> </script>
          復(fù)制代碼

          新方案

          在現(xiàn)在的構(gòu)建階段基本上都不需要人工操作了,都是使用構(gòu)建工具比如Wbpack、Gulp、Grunt等構(gòu)建工具自動(dòng)構(gòu)建。比如在使用Webpack構(gòu)建的時(shí)候,會(huì)根據(jù)文件名或文件內(nèi)容自動(dòng)計(jì)算hash值來給文件命名,當(dāng)內(nèi)容或文件名發(fā)生改變的時(shí)候,構(gòu)建出來的文件名也一定會(huì)不一樣,這樣也解決了強(qiáng)緩存還在有效期內(nèi)的問題。

          pragma

          pragma是舊產(chǎn)物,已經(jīng)逐步拋棄,有些網(wǎng)站為了向下兼容還保留了這個(gè)字段。pragma的值為no-cache時(shí),表示禁用緩存。優(yōu)先級(jí)是 pragma > cache-control > expires。

          流程圖

          有了這張流程圖,可以讓你們理解的更清楚。

          緩存的配置

          如果我們使用Nginx作為Web服務(wù)器,我們可以如下配置

          location / {

            # 其它配置
            ...

            if ($request_uri ~* .*[.](js|css|map|jpg|png|svg|ico)$) {
              #非html緩存1個(gè)月
              add_header Cache-Control "public, max-age=2592000";
            }

            if ($request_filename ~* ^.*[.](html|htm)$) {
              #html文件使用協(xié)商緩存
              add_header Cache-Control "public, no-cache";
            }
          }

          復(fù)制代碼

          緩存到底存在哪?

          很多小伙伴會(huì)好奇,這緩存到底存在哪里了呢?別急,我們接著往下講。

          按緩存位置分類我們可以分為memory cache、disk cache、Service Worker三類,我們可以在 Chrome 的開發(fā)者工具中,Network -> Size 一列看到一個(gè)請(qǐng)求最終的處理方式:如果是大小 (多少 K, 多少 M 等) 就表示是網(wǎng)絡(luò)請(qǐng)求,否則會(huì)列出 from memory cachefrom disk cachefrom ServiceWorker就表示命中了緩存。

          • memory cache 是內(nèi)存中的緩存,(與之相對(duì) disk cache 就是硬盤上的緩存)。按照操作系統(tǒng)的常理:先讀內(nèi)存,再讀硬盤。
          微信截圖_20220119110918.png
          • disk cache 也叫 HTTP cache,顧名思義是存儲(chǔ)在硬盤上的緩存,因此它是持久存儲(chǔ)的,是實(shí)際存在于文件系統(tǒng)中的。而且它允許相同的資源在跨會(huì)話,甚至跨站點(diǎn)的情況下使用,例如兩個(gè)站點(diǎn)都使用了同一張圖片。
          微信截圖_20220119110855.png
          • 上述的緩存策略以及緩存/讀取/失效的動(dòng)作都是由瀏覽器內(nèi)部判斷進(jìn)行的,我們只能設(shè)置響應(yīng)頭的某些字段來告訴瀏覽器,而不能自己操作。service work給予了我們另外一種更加靈活,可以直接的操作方式。我們可以從 Chrome 的 Application找到Service Workers。這個(gè)緩存是永久性的,即關(guān)閉 TAB 或者瀏覽器,下次打開依然還在(而 memory cache 不是)。有兩種情況會(huì)導(dǎo)致這個(gè)緩存中的資源被清除:手動(dòng)調(diào)用 API cache.delete(resource) 或者容量超過限制,被瀏覽器全部清空。

          后記

          本文為筆者個(gè)人學(xué)習(xí)筆記,如有謬誤,還請(qǐng)告知,萬分感謝!如果本文對(duì)你有所幫助,還請(qǐng)點(diǎn)個(gè)贊~~

          來自:蘇蘇同學(xué)

          https://juejin.cn/post/7052527032491573279

          最后

          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會(huì)很認(rèn)真的解答喲!
          回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對(duì)你有幫助,在看」是最大的支持
           》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持
          瀏覽 46
          點(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>
                  韩国无码一区二区 | 欧美日韩视频高清 | 精品黄网| 免费一级全黄少妇性色生活片 | 成人催情爱爱免费视频 |