博客 / 詳情

返回

http緩存詳解( 直接看圖,超易懂🤗 )

前言

你瞭解http緩存嗎?http請求在什麼狀態下會返回304狀態碼?

下面5張圖,花了一晚上整理畫出來🙈,圖畫的不太好看,但意思十分明確,不要太嫌棄喔。相信看完後,能讓你對http緩存有比較深刻🤔的瞭解。

Http 緩存機制作為 web 性能優化的重要手段,對於從事 Web 開發的同學們來説,應該是知識體系庫中的一個基礎且重要的環節,同時對於有追求的前端童鞋來説也是必備的知識技能。

知識鋪墊

瞭解瀏覽器和服務器間通信時的請求報文及響應報文,HTTP報文就是瀏覽器和服務器間通信時發送及響應的數據塊。
參考

緩存命中規則

我們都知道前端發送請求時,命中緩存會直接返回緩存數據。那麼緩存到底從哪裏來的?其實我們可以認為瀏覽器存在這麼一個緩存數據庫,用於存儲緩存信息。

在客户端首次請求數據時,緩存數據庫中沒有對應的緩存數據,需要請求服務器,服務器返回後,
將數據及緩存規則存儲至緩存數據庫中。

http_cache1.png

HTTP緩存有多種規則,根據是否需要重新向服務器發起請求來分類,一般將其分為兩大類(強制緩存對比緩存)

強制緩存如果生效,不需要再和服務器發生交互,而對比緩存不管是否生效,都需要與服務端發生交互。

強制緩存

響應頭中一定有cache-controlexpires屬性。
其http的狀態碼返回:Status Code: 200 (from disk cache),説明強制緩存已被命中使用。

Expires為服務端返回的到期時間。即下一次請求時,請求時間小於服務端返回的到期時間,直接使用緩存數據。作為HTTP 1.0的作品,所以它基本可以忽略。

另一個問題是,到期時間是由服務端生成的,但是客户端時間可能跟服務端時間有誤差,這就會導致緩存命中的誤差。
所以HTTP 1.1 的版本,使用Cache-Control替代。

Cache-Control 是最重要的規則。常見的取值有no-cache、no-store、max-age、private、public、,默認為private。見下表:

字段值 作用
no-cache 防止從緩存中返回過期的資源,所以使用之前,需要和源服務器發起請求比對過期時間
no-store 這個指令才是真正的不進行緩存,暗示請求報文中可能含有機密信息,不可緩存
max-age 在指定時間內,緩存服務器不再對資源的有效性進行確認,可以使用
private 只有某個在通過緩存服務器的時候,得到緩存資源
public 所有的用户在通過緩存服務器的時候,都可以緩存這個資源。

Cache-Control 中,這些值可以自由組合,多個值如果衝突時,也是有優先級的,而no-store優先級最高。如下圖:

image.png

強制緩存的緩存機制,如下圖:

http_cache2.png

http_cache3.png

對比緩存

顧名思義,需要進行比較判斷是否可以使用緩存。
響應頭中一定有etaglast-modified屬性。
其http的狀態碼返回傳説中的:Status Code: 304

last-modified:

  • 服務器第一次響應請求時,告訴瀏覽器資源的最後修改時間,並存儲到瀏覽器端。
  • 再次請求時,請求頭中攜帶If-Modified-Since字段,將上次請求服務器資源的最後修改時間傳到服務器與被請求資源的最後修改時間進行比對。
  • 若資源的最後修改時間大於If-Modified-Since的值,説明資源又被改動過,則響應整片資源內容,返回狀態碼200。
  • 若資源的最後修改時間小於或等於If-Modified-Since,説明資源無新修改,則響應HTTP 304,告知瀏覽器繼續使用所保存的cache。

etag:

  • 服務器資源是否被修改的唯一標誌。首次請求唯一標誌被存到客户端數據庫。
  • 同理,再次請求時,請求頭中攜帶If-None-Match字段。與被請求資源的唯一標識進行比對
  • 若不同,説明資源又被改動過,則響應整片資源內容,返回狀態碼200;
  • 若不同,説明資源沒有被改動過,則響應HTTP 304,告知瀏覽器繼續使用所保存的cache。

對比緩存的緩存機制,如下圖:

http_cache4.png

http_cache5.png

http緩存優先級

強制緩存優先級 高於 對比緩存。 也就是説,當執行強制緩存的規則時,如果緩存生效,直接使用緩存,不再執行對比緩存規則

強制緩存: cache-control (http1.1) > expires(http1.0)、
對比緩存: etag(傳送If-None-Match) > last-modified (傳送If-Modified-Since)

總結

總的來説,http緩存的概念是比較抽象的。這裏提供一個方法,可以讓大家能更好的消化、吸收:我們可以通過nodejs框架快速生成接口,在接口中設置不同的緩存機制,通過 budo 、 anywhere 、 http-server 的方式快速生成靜態文件服務器,去調用接口,然後在請求後對有無緩存的情況做對比。只要我們真正的動手實踐,才能更快更準確的掌握知識點。順便我們還可以通過服務實踐一下http 301302 狀態碼的區別。

面試過程中你有被問倒過哪些http問題?歡迎在下方留言討論。如果發現文章中有誤的地方歡迎指出。如果覺得有幫助,不妨點贊、關注支持一下,非常感謝!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.