瀏覽器緩存那些事

瀏覽器讀取資源的流程

  • 瀏覽器在加載資源時,根據請求頭的expires和cache-control判斷是否命中強緩存,是則直接從緩存讀取資源,不會發請求到服務器。
  • 若是沒有命中強緩存,瀏覽器必定會發送一個請求到服務器,經過last-modified或者etag驗證資源是否命中協商緩存,若是命中,服務器會將這個請求返回,可是不會返回這個資源的數據,依然是從緩存中讀取資源
  • 若是前面二者都沒有命中,直接從服務器加載資源

強制緩存(不發送請求)

  1. 如何設置
    一般咱們會同時設置expires和cache-control兩種,保證不管在http1仍是1.1的狀況下都有效css

    • expires
      過時時間,若是設置了時間,則瀏覽器會在設置的時間內直接讀取緩存,再也不請求
    • cache-controlhtml

      http1.1新標準,包括這些屬性:算法

      (1)max-age:用來設置資源(representations)能夠被緩存多長時間,單位爲秒;
      (2)s-maxage:和max-age是同樣的,不過它只針對代理服務器緩存而言;
      (3)public:指示響應可被任何緩存區緩存;
      (4)private:只能針對我的用戶,而不能被代理服務器緩存;
      (5)no-cache:強制客戶端直接向服務器發送請求,也就是說每次請求都必須向服務器發送。服務器接收到請求,而後判斷資源是否變動,是則返回新內容,不然返回304,未變動。這個很容易讓人產生誤解,令人誤覺得是響應不被緩存。實際上Cache-Control:no-cache是會被緩存的,只不過每次在向客戶端(瀏覽器)提供響應數據時,緩存都要向服務器評估緩存響應的有效性。
      (6)no-store:禁止一切緩存(這個纔是響應不被緩存的意思)。
  2. 緩存的兩種表現形式瀏覽器

    • memory cache

      來自於內存的數據,會隨着進程的結束而清除,讀取速度相對快(0ms)
      通常存放腳本,圖片,字體等文件緩存

    • disk cache

      來自於硬盤的數據,不會隨着進程的結束而清除,讀取速度慢於memory cache(2-10ms 硬盤讀寫的IO操做)
      通常存放css文件服務器

      根據經驗狀況來看:瀏覽器的實際處理邏輯是這樣的性能

      首次加載資源 -> 200 -> 關閉標籤頁
      再次進入 -> 200 from disk cache -> 刷新 -> 200 from memory cache
      (不過好像css都是from disk cache, base64都是from memory cache)字體

協商緩存(發送請求)

客戶端向服務端發送請求時候(沒有命中強制緩存),服務端會檢查是否有對應的標識,沒有則返回200並生成一個新的標識帶到header,下次在請求的時候服務端檢查到對應的這個標識並作相應的校驗,經過則返回304,讀取緩存。ui

  • Last-modify / If-modify-since

    瀏覽器首次請求資源的時候,服務器會返回一個last-Modify到header中. Last-Modify 含義是最後的修改時間。
    當瀏覽器再次請求的時候,request header會帶上 if-Modify-Since,該值爲以前返回的 Last-Modify。服務器收到if-Modify-Since後,根據資源的最後修改時間(last-Modify)和該值(if-Modify-Since)進行比較,若是相等的話,則命中緩存,返回304,不然, 則會給出200響應,而且更新Last-Modify爲新的值代理

  • Etag / If-none-match(http1.1規範)
    ETag的原理和上面的last-modified是相似的。ETag對當前請求的資源作一個惟一的標識。該標識能夠是一個字符串,文件的size,hash等。只要可以合理標識資源的惟一性並能驗證是否修改過就能夠了。ETag在服務器響應請求的時候,返回當前資源的惟一標識(它是由服務器生成的)。可是隻要資源有變化,ETag會從新生成的。瀏覽器再下一次加載的時候會向服務器發送請求,會將上一次返回的ETag值放到request header 裏的 if-None-Match裏面去,服務器端只要比較客戶端傳來的if-None-Match值是否和本身服務器上的ETag是否一致,若是一致說明資源未修改過,所以返回304,若是不一致,說明修改過,所以返回200。而且把新的Etag賦值給if-None-Match來更新該值。

協商緩存兩種方式對比

  • 在精度上,ETag要優先於 last-modified。

    last-modified這種方式精度差在哪裏:
    a. 一些文件也許會週期性的更改,可是他的內容並不改變(僅僅改變的修改時間),這個時候咱們並不但願客戶端認爲這個文件被修改了
    b. 某些文件修改很是頻繁,好比在秒如下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改沒法判斷(或者說UNIX記錄MTIME只能精確到秒);

  • 在性能上,Etag要遜於Last-Modified,Last-Modified須要記錄時間,而Etag須要服務器經過算法來計算出一個hash值。
  • 在優先級上,服務器校驗優先考慮Etag。

如何設置index.html不被緩存

<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">  <!-- http1.1標準 -->
<meta http-equiv="Pragma" content="no-cache">  <!-- http1.0標準 -->
相關文章
相關標籤/搜索