[Front-end] Browser Cache : 熟悉的陌生人 I I

Huge Gun
9 min readAug 22, 2020

--

本篇是 Cache 系列的第二篇,在上一篇講完 Cache 機制之後,這篇會來說說Cache 儲存的位置,也會填坑第一篇結尾提到的兩個重點,接下來會說的大項如下:

  1. Cache 存放的位置 & 優先級別
  2. Cache Status Code
  3. Cache-Control 的控制屬性

那麼就用這三個點來開啟進入 Browser Cache 的第二站吧!!

Cache 存放的位置 & 優先級別有哪些

一般來說 Cache 最常見的存放地方是 2種,以目前來說全部可以有 4種位置,分別是以下四種

  1. Memory Cache
  2. Disk Cache
  3. Service Worker
  4. Push Cache

前面說的常見沒特別設定的話,就是前兩種,本篇會著重在前兩說的解說,接下來看一下這些的差異吧!

Memory Cache

看名子也知道它是放在我們的 RAM 裡面,也是最常見到的 Cache 位置之一,打開 Chrome DevTools 來看的話,就如下圖:

Memory Cache

特性 :

  • 讀取 RAM 中的 Data 比 Disk 快。
  • 適合較常變動的 File。

缺點:

  • Cache 持續性較短,一但 Page 關掉 RAM 就一起釋放了。

Additional Tips:

  • 雖然 Memory 比 Disk 快,但我們也無法將全部的 Cache 往 Memory 塞,畢竟 Memory 空間都比 Disk 小,且持續性短。

Disk Cache

就是放在硬碟當中的 Cache,也是最常見到的 Cache 位置之一,打開 Chrome DevTools 來看的話,就如下圖:

Disk Cache

特性 :

  • Cache 持續性較長,Disk Cache 在 Cache 中的覆蓋面基本上是最大的。
  • 適合較常變少動的 File。
  • 適合 Size 較大的 File。

缺點:

  • 讀取 Data 的速度比 Memory 慢。

Additional Tips:

  • 若當下的系統 RAM 使用率很高的話,Cache 會優先存進 Disk,即便是小 Size 也一樣。

Service Worker

Service Worker 是運行在 Browser 背後的獨立執行緒,它也可以用來達到Cache 的效果,初步你可以理解為它是隻 JS 檔,運行在我們 Client 的Proxy,當 Page 有變動 or 發生 Request 時,會先查看網頁是否有 Service Worker,如果有註冊了而且有符合的 Cache Source File,就不把 Request 丟給 Server 了,直接讓 Service Worker 拿 Cache 做 Respond 回應給 Client,常看到它被用來做

  • Handle Browser 的存儲 Data。
  • Handle HTTP Request。
  • Sand Notification。

等等…能在背後運行的事情,它的 Flow 如下圖:

Source: 開啟Service Worker

可以看到當有 Service Worker 它的 Flow 是走 1 2 3 的步驟,與我們在第一篇提到的差異是,沒有註冊它的話,Flow 是 Page 到 Cache 再到 Network,而強 Cache” & “協商 Cache 則是在這段才發生的檢查。

嚴格來說它已經偏向於 PWA 的領域,所以本篇不會在這做太多的展開,後續會專門來說說,好奇的小夥伴可以先看 [這裡]

Push Cache

它是 HTTP/2 中新增的 Cache 機制,當前面三種 Cache 都不符合時,它才會被使用,但他只存活在 Client 與 Server 建立起 Session 連線時的那段時間,Cache 持續性非常的短,目前在開發的使用上也比前兩種來的少很多,所以本篇也不會展開詳細解說,好奇的小夥伴可以先看 [這裡]

Cache 的優先級別

拿取與存放 Cache Source 的優先順序,我們來擴充一下上面那張圖,幫它的 Cache 部分加上的 Memory & Disk 兩個存放位置,就如下圖紅色框線的部分:

Source: 開啟Service Worker

從上圖可以得出拿取的順序了

  1. 先查找 Memory,如果有找到,從 Memory 中拿取 File 返回
  2. Memory 沒有,就去 Disk 找 ,有的話就從 Disk 中拿取 File 返回
  3. 如果 Disk 中也沒有,那就發出 HTTP Request 給 Network
  4. 從 Network 拿到後再存進去 Memory or Disk 以便下次使用

至於存放的順序

  1. 沒有特別設定的話會先放入 Memory
  2. 若當前 Memory 使用率很高被占滿,就往 Disk 存

以上就是關於 Cache 的位置 & 拿取跟存放順序,接著再來看看 Status Code 的部分啦!

Cache Status Code

這個 Status Code 就是大家熟知的 HTTP Respond,在眾多狀態碼中跟我們 Browser Cache 有關係的且常見的只有2個 (200 與 304),今天就來探討一下,就直接上圖來解釋吧!!

Chrome Cache Status Code

可以看到 Render 同一個 Page 用的 Source,有 200 與 304,先來說說這兩個狀態碼的差異

304 (協商 Cache)

以上圖得第一筆為例,在一篇有提到過,若是該 Source 的判斷機制走到了比對 Last-Modified 或是E-Tag 階段,之後被判定不用跟 Server 拿新的,則得到的回應就是 304,請注意顯示 304 時是有發出 Request 給 Server 的,只是 Server 回應說沒更動,就不用更新 Source,直接沿用 Client Cache

200 (強 Cache)

顯示為 200 的話表示發出的 Request 是成功的,有被 Server 做出 OK 的回應,並且有拿到最新的 Source File,而該次的 Server Respond 是可以被 Client Cache 的 or 用來更新舊 Source,以便下次使用。

Status Code 對應 Cache 存放的位置

上圖中右邊框起來的就是存放的位置,通常在 DevTool 上看存放位置的顯示會有三種:

  • memory cache: 沒對 Server 發出 Request,直接讀取 Client Cache。
  • disk cache: 沒對 Server 發出 Request,直接讀取 Client Cache。
  • file size: 會對 Server 發出 Request,表示已經問過 Server 了。

Cache-Control 的控制屬性

Cache-Control 它是我們可以寫入在 Request Header 中的一個指令,並且可以透過它來跟 Server 溝通,以達到控制 Cache 的機制,直接先上一張圖來看看它長怎樣吧!!

Source: stackoverflow

而 Cache-Control 它是單向的輸入,所以送出後不一定每次都可以在 Respond 中看到,在上圖中我們也看到它又有區分以下兩種類型:

  1. Request Cache-Control
  2. Respond Cache-Control

這篇會聚焦在第一種,至於第二種的話,好奇的小夥伴可以先看[這裡],接著來仔細看看 Request Cache-Control ,一般常見到它有的屬性會有 7個,分別屬於兩種不同類型指令,如下:

Cacheability (可Cache 性 )

Cache-Control: no-cache

Client 可以 Cache Source,但是要用這個 Source 時,都必須重新驗證是否有過期,表示每次都會發 Request 去問 Server,若當 Server 回 Source 仍有效,可跳過 HTTP Respond Download Source,就是前面說的 304 的狀況。

Cache-Control: no-store

Client 不存任何這項 Source 相關的 Request & Respond,就是不用任何的 Cache,所以每次都會去跟 Server 拿,所以每次的 Status Code 都會是 200,而 Cache 位置都會顯示是 File Size。

Cache-Control: no-transform

Proxy 不能對 Source 做轉換 or 修改,像是 Request Header 中的 Content-Type 之類的,或者是對 Image 格式做轉換,比方說 [Google’s Light Mode] 這類的都會無法執行。

Cache-Control: only-if-cached

Client 對於該項 Source 只接受已經有被 Cache 過的 File,且不會再向 Server 確認是否有過期。

Expiration (期限性)

Cache-Control: max-age=<seconds>

設定該項 Source Cache 存儲的最大時限,超過這個時間之後會被判定是過期,注意這個單位的時間與第一篇提到的 Expires 相反,它是相對於Request 的時間。

Cache-Control: max-stale[=<seconds>]

Client 設定可以接受以過期的該項 Source Cache,表示這個 Cache 雖然進入到協商緩存階段,並且被判定過期,本來應該重新執行 HTTP Respond Download Source,但可以透過這個設定的秒數,再容許這段時間內照樣用舊的 Cache File。

Cache-Control: min-fresh=<seconds>

表示設定 Client 在這個秒數之內,每次 Get Source Cache 都一定要保持在最新的。

以上就是 Browser Cache 的第二篇,也填了第一篇的一些坑,不過也還有滿多關於 Cache 的其他部分沒有說到,比方說: Respond Cache-Control 或是 Cache 如何影響 User 的操作行為等等的,後續會再寫第三篇,希望本系列對想搞清楚 Cache 的人有幫助啦!!

--

--

Huge Gun

槍再大把,沒子彈是不行的;通過學習,鍛造自己的子彈!https://github.com/HsienW