tft每日頭條

 > 生活

 > 關于浏覽器緩存你知道多少

關于浏覽器緩存你知道多少

生活 更新时间:2024-07-24 11:14:46

關于浏覽器緩存你知道多少?分享一些實用或有意思的東西,發現代碼之美專注深度和最佳實踐,希望打造的是一個高質量的公衆号,今天小編就來說說關于關于浏覽器緩存你知道多少?下面更多詳細答案一起來看看吧!

關于浏覽器緩存你知道多少(關于浏覽器緩存你知道多少)1

關于浏覽器緩存你知道多少

分享一些實用或有意思的東西,發現代碼之美。專注深度和最佳實踐,希望打造的是一個高質量的公衆号。

在前端開發中,我們在提到性能優化的時候總會提到一點:合理設置緩存。我們該如何從這方面入手來考慮提高網站性能呢?

前言

我們都知道 HTML5 引入了應用程序緩存,可以在沒有網絡的情況下進行訪問,同時,HTML5 還引入了 storage 本地存儲。這些都屬于應用緩存。

本篇文章主要内容是和浏覽器緩存相關的,也可以說是 HTTP 緩存。

什麼是浏覽器緩存

MDN 上是這樣解釋浏覽器緩存的:

A browser cache holds all documents downloaded via HTTP by the user ... without requiring an additional trip to the server.

意思就是,浏覽器緩存保存着用戶通過 HTTP 獲取的所有資源,再下一次請求時可以避免重複向服務器發出多餘的請求。

通俗的說,就是在你訪問過一次某個網站之後,這個站點的文字、圖片等所有資源都被下載到本地了,下次再訪問該網站時判斷是否滿足緩存條件,如果滿足就不用再花費時間去等待資源的獲取了。

浏覽器緩存的分類

一般來說浏覽器緩存可以分為兩類:

強緩存

協商緩存(對比緩存)

我們需要知道的是,浏覽器在加載資源時,會先判斷是否命中強緩存再驗證是命中協商緩存

其它的的具體細節,稍後會展開來說。

強緩存

浏覽器在加載資源時,會先根據本地緩存資源的 header 中的信息判斷是否命中強緩存,如果命中則直接使用緩存中的資源不會再向服務器發送請求。

從圖中可以看出,強緩存一般是這樣一個流程:

    查看 header 頭中的 Expire 和 Cache-control 來判斷是否滿足規則;

    如果滿足規則,就返回緩存的數據;

    如果不滿足規則,就向服務器發送請求;

    服務器返回數據;

    将新數據存入緩存。

所以我們主要就是關注 Expire 和 Cache-control 這兩個字段。

Expire

同樣地,我們看看MDN中如何解釋這個字段:

The Expires header contains the date/time after which the response is considered stale.

這個字段包含了一個時間,過了這個時間,響應将會失效。

也就是說,Expire 這個字段表示緩存到期時間,我們來打開一個網站并查看 Response Header 看看這個字段:

  • Expires:Fri, 27 Oct 2017 07:55:30 GMT

    可能在你查看這的時候發現時間不對啊,怎麼都已經是過去了 ~

    GMT 表示的是格林威治時間,和北京時間相差8小時。

    上面的這個時間表示的是 2017年10月27日15:55:30。

    通過設置 Expire 來設置緩存有一個緻命缺點:

    可以看出,這個是個絕對時間,也就是說,如果我修改了客戶端的本地時間,是不是就會導緻判斷緩存失效了呢。

    Cache-Control

    既然不能設置絕對時間,那我就設置個相對時間呗。

    在 HTTP/1.1 中,增加了一個字段 Cache-Control ,它包含一個 max-age 屬性,該字段表示資源緩存的最大有效時間,這就是一個相對時間。

  • Cache-Control:max-age=600

    這個表示的就是最大有效時間是 600s ,對的,它的單位是秒。

    Cache-Control 除了 max-age 屬性之外還有一些屬性:

    no-cache:需要進行協商緩存,發送請求到服務器确認是否使用緩存。

    no-store:禁止使用緩存,每一次都要重新請求數據。

    public:默認設置。

    private:不能被多用戶共享。

    現在基本上都會同時設置 Expire 和 Cache-Control ,Cache-Control 的優先級别更高。

    協商緩存

    當強緩存沒有命中的時候,浏覽器會發送一個請求到服務器,服務器根據請求頭中的部分信息來判斷是否命中緩存。如果命中,則返回 304 ,告訴浏覽器資源未更新,可使用本地的緩存。

    從圖中可以看出,協商緩存一般是這樣一個流程:

      把資源标識,比如 If-Modify-Since 或 Etag 發送到服務器,确認資源是否更新;

      如果資源未更新,請求響應返回的http狀态為 304 并且會顯示一個 Not Modified 的字符串,告訴浏覽器使用本地緩存;

      如果資源已經更新,返回新的數據;

      将新數據存入緩存。

    Last-Modified,If-Modified-Since

    浏覽器第一次請求資源的時候,服務器返回的 header 上會帶有一個 Last-Modified 字段,表示資源最後修改的時間。

  • Last-Modified: Fri, 27 Oct 2017 07:55:30 GMT

    同樣的,這是一個 GMT 的絕對時間。

    當浏覽器再次請求該資源時,請求頭中會帶有一個 If-Modified-Since 字段,這個值是第一次請求返回的 Last-Modified 的值。服務器收到這個請求後,将 If-Modified-Since 和當前的 Last-Modified 進行對比。如果相等,則說明資源未修改,返回 304,浏覽器使用本地緩存。

    well,這個方法也是有缺點的:

    最小單位是秒。也就是說如果我短時間内資源發生了改變,Last-Modified 并不會發生變化;

    周期性變化。如果這個資源在一個周期内修改回原來的樣子了,我們認為是可以使用緩存的,但是 Last-Modified 可不這樣認為。

    所以,後來又引入一個 Etag。

    Etag

    Etag 一般是由文件内容 hash 生成的,也就是說它可以保證資源的唯一性,資源發生改變就會導緻Etag 發生改變。

    同樣地,在浏覽器第一次請求資源時,服務器會返回一個 Etag 标識。當再次請求該資源時, 會通過If-no-match 字段将 Etag 發送回服務器,然後服務器進行比較,如果相等,則返回 304 表示未修改。

    **Last-Modified 和 Etag 是可以同時設置的,服務器會優先校驗 Etag,如果 Etag 相等就會繼續比對 Last-Modified,最後才會決定是否返回 304。**

    總結

    當浏覽器再次訪問一個已經訪問過的資源時,它會這樣做:

      看看是否命中強緩存,如果命中,就直接使用緩存了;

      如果沒有命中強緩存,就發請求到服務器檢查是否命中協商緩存;

      如果命中協商緩存,服務器會返回 304 告訴浏覽器使用本地緩存;

      否則,返回最新的資源。

    更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

    查看全部
  • 相关生活资讯推荐

    热门生活资讯推荐

    网友关注

    Copyright 2023-2024 - www.tftnews.com All Rights Reserved