iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
自我挑戰組

為了成為更好的前端,我開始在乎的那些事系列 第 28

[Day 28] 網路常識 - (13) HTTP cache - 那些 browser 默默幫你做的請求優化

  • 分享至 

  • xImage
  •  

在前面 HTTP 的歷史中,有提到在 HTTP/1.0 和 HTTP/1.1 時,有加入了些優化的機制,讓瀏覽器可以 cache 一些之前請求過的 API 資料,不用每次都跟 Server 要,我們今天就來詳細的介紹一下

 

HTTP cache 流程大綱

https://ithelp.ithome.com.tw/upload/images/20231013/20148944JndX6wNa5u.png

HTTP cache 的流程大綱,大致以幾個部分組成:

  1. Browser 發出 request
  2. 檢驗 cache 的 request 資料有沒有過期,沒有過期就用瀏覽器的 cache
  3. 檢驗 Server 有沒有新資料,沒有的話就用瀏覽器的 cache
  4. Server 回傳新資料給 Browser,Browser 同時 cache 新資料

 

HTTP/1.0 的 cache 機制

https://ithelp.ithome.com.tw/upload/images/20231014/20148944NOm83O3RiP.png

在 HTTP/1.0 時,其實已經有 http cache 的機制,雖然設計上還不太完善,但是基本上流程跟上面相同,而有一些相對應的 HTTP/1.0 的 header 可以協助整個 cache 機制的運作,我們就分以下 2 個部分介紹:

  • 檢驗 request cache 有沒有過期
  • 檢驗 Server 有沒有新資料

 

檢驗 request cache 有沒有過期

https://ithelp.ithome.com.tw/upload/images/20231014/20148944EnbfhCWsxy.png

在 HTTP/1.0 中,提供了 Expires header,讓我們可以用絕對時間,例如

Expires: Fri, 13 Oct 2023 07:28:00 GMT

 

如果瀏覽器中,有紀錄上次此 http request Expires 的時間,且現在時間比 Expires 紀錄的時間早,那 Browser 就會直接幫我們去 Browser Cache 拿取上一次的資料,就可以快速取得資料

但如果沒有 Expires 的值,或者超過 Expires 的時間,我們就會嘗試去跟 Server 要資料

 

這裡 Expires 其實有個問題,因為 Expires 紀錄的是絕對時間,當我們把我們電腦或 Server 的時間做更改後,就會導致 Browser 判斷錯誤,導致沒有辦法取到正確的資料,這部分在 HTTP/1.1 的時候,利用新的細粒度更高的 Cache-Control header 來控制,解決了這個問題,下面會再詳細說明

 

檢驗 Server 有沒有新資料

https://ithelp.ithome.com.tw/upload/images/20231014/201489448YTGJcdqPT.png

Expires 已經過期時,Browser 就會嘗試去跟 Server 拿資料,但同時也會去檢查上次 API 回傳時,如果有說明上一次跟新時間是什麼,也就是 Last-Modified,就會同時在發 request 時,加入 If-Modified-Since: <Last-Modified value> 到 request 中,去跟 Server 做比對,看 Browser 中儲存的 Last-Modified 是不是跟 Server 的時間一樣,

Last-Modified: Fri, 13 Oct 2023 07:28:00 GMT

 

  • ✅ 如果 Server 有新的更新,也就是 Server's Last-Modified 日期在 Browser's Last-Modified 之後,那就表示我們應該要取得新的 Server 資料,同時把新的資料更新到 Browser cache 中
  • 🟡 如果 Server 沒有更新,也就是 Server's Last-Modified 日期與 Browser's Last-Modified 在同一天,那 Server 就會回傳 304 Not Modified,並且 Browser 可以沿用原本的 cache

 

 

HTTP/1.1 的 cache 機制

https://ithelp.ithome.com.tw/upload/images/20231014/20148944REE0QH3qIe.png

在 HTTP/1.1 中,完善了很多對 cache 機制的控制,讓 cache 機制能如預期的進行,例如:

  • Cache-Control:利用相對時間,讓 cache 的期限同步,例如利用 max-age: 86400 表示只會存在現在的時間 + 1 天,就不會有絕對時間不一樣造成的問題了,cache 會在預期的 X 天後結束
  • ETag:利用內文產生的 hash 值,可以比較 Browser cache 的內容和 Server 的內容有無差異,就可以精準的知道需不需要重取內容了

 

檢驗 request cache 有沒有過期

https://ithelp.ithome.com.tw/upload/images/20231014/20148944Fnj3ioScl1.png

在有了 Cache-Control 的 header 後,我們可以對 Browser cache 儲存的時間有更高細粒度的控制,可填入的值有:

  • max-age: cache 可停留的秒數
  • public: 此 cache 可以被儲存在任何地方,像是 Browser, CDN 等
  • private:只有目標 Browser 能儲存此 cache
  • no-store:不要儲存 cache
  • 🚩 no-cache每次都先去跟 server 驗證,如果 Server 回傳 304 Not Modified,再去取得 Browser cache

Cache-ControlExpires 同時存在的話,會以 Cache-Control 為主,覆蓋掉 Expires 的功能

 

這些值也可以組合在一起,範例如下

Cache-Control value Explanation
max-age=86400 response 可以被瀏覽器和中介緩存(例如 CDN)緩存最多1天(60秒 x 60分鐘 x 24小時)
private, max-age=600 response 可以被瀏覽器緩存最多10分鐘(60秒 x 10分鐘),但不能被中介緩存緩存
public, max-age=31536000 response 可以被任何緩存(包括瀏覽器和中介緩存)儲存最多1年
no-store 不允許緩存回應,每次請求都必須完整地重新獲取回應

 
 

檢驗 Server 有沒有新資料

https://ithelp.ithome.com.tw/upload/images/20231014/201489448dfLeiiSAP.png

比起在 HTTP/1.0 時,只能利用 Last-Modified 時間去比對資料是否有更新過,在 HTTP/1.1 中,我們可以利用 內文 產出的 hash 值,也就是 Etag 來比較 Browser cache 和 Server 的資料是否有異動,當 我們將 Etag 加入到 If-No-Match 的 header 中,發出 request 值

  • 如果 Etag 不相符,則重新取得 Server 資料,並把新的 Etag 覆寫到 Browser cache 中
  • 如果 Etag 相符,則 Server 回傳 304 - Not Modified,可以直接去跟 Browser cache 要資料

https://ithelp.ithome.com.tw/upload/images/20231014/20148944xNUeO6DgOV.png
(圖片來源:https://web.dev/articles/http-cache#flowchart)

 

Etag 的優先度會高於 Last-Modified,會優先以 Etag 比較

 
 

今天小結

  • 知道 http cache 的流程就是 request -> 檢驗 cache 有沒有過期,沒過期就用 -> 檢驗 server 有沒有新資料,沒有就用 cache -> 有新資料就回傳新資料
  • 知道 HTTP/1.0 時,就已經有整體的 cache 流程,利用 ExpiresLast-Modified 可達到 cache 流程機制,但這些 header 設計上還有許多漏洞,容易 Server Client 不同步
  • 知道 HTTP/1.1 新增 Cache-controlETag,有更高的細粒度可以控制 cache,使得 Server 和 Client 的 cache 行為一致

 

參考資源


上一篇
[Day 27] 網路常識 - (13) HTTP 的發展史 - HTTP/3.0: 改善傳輸層的效能 (待補)
下一篇
[Day 29] 網路常識 - (14) HTTPS - 在 HTTP 沒有 CA 憑證的時代,產生的資安問題
系列文
為了成為更好的前端,我開始在乎的那些事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言