一般而言,快取能夠儲存資料來提高效能,因此日後對於相同資料的要求可以更快提供。例如,網路快取資源可避免往返伺服器。快取的運算結果可能會省略時間進行相同的計算。
Chrome 使用快取機制有很多種,而 HTTP 快取就是其中一例。
Chrome 的 HTTP 快取目前如何運作
自 85 版起,Chrome 會使用個別資源網址做為快取金鑰,來快取從網路擷取的資源。(快取金鑰可用來識別快取資源)。
以下範例說明單張圖片在三種不同環境中的快取和處理方式:
![快取金鑰:https://x.example/doge.png](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsxexam-d673e1bd1a43f.png?authuser=6&hl=zh-tw)
https://x.example/doge.png
}
使用者造訪了要求圖片 (https://x.example/doge.png
) 的頁面 (https://a.example
)。系統會向網路要求該圖片,並以 https://x.example/doge.png
做為索引鍵進行快取。
![快取金鑰:https://x.example/doge.png](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsxexam-f8c1f9f7d95ce.png?authuser=6&hl=zh-tw)
https://x.example/doge.png
}
同一使用者造訪另一個網頁 (https://b.example
),該網頁要求相同的圖片 (https://x.example/doge.png
)。瀏覽器會使用圖片網址做為金鑰,檢查其 HTTP 快取,確認是否已快取這項資源。瀏覽器會在快取中找到相符結果,因此會使用資源的快取版本。
![快取金鑰:https://x.example/doge.png](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsxexam-62cac78cd2789.png?authuser=6&hl=zh-tw)
https://x.example/doge.png
}
就算圖片是從 iframe 內載入,也不會受到影響。如果使用者造訪包含 iframe (https://d.example
) 的其他網站 (https://c.example
),且 iframe 要求了相同的圖片 (https://x.example/doge.png
),則瀏覽器還是可以從快取載入圖片,因為所有網頁的快取金鑰都相同。
從效能的角度來看,這項機制長期運作至今都很良好。不過,網站回應 HTTP 要求所花的時間可證明瀏覽器過去曾存取相同的資源,因此瀏覽器可能會受到安全性和隱私權攻擊,如下所示:
- 偵測使用者是否曾造訪特定網站:攻擊者可以檢查快取是否含有特定網站或網站同類群組的資源,藉此偵測使用者的瀏覽記錄。
- 跨網站搜尋攻擊:攻擊者可檢查特定網站使用的「沒有搜尋結果」圖片是否位於瀏覽器的快取中,藉此偵測使用者搜尋結果中是否有任意字串。
- 跨網站追蹤:快取可用來儲存類似 Cookie 的 ID,做為跨網站追蹤機制。
為降低這類風險,Chrome 將從 Chrome 86 版開始將 HTTP 快取分區,
快取分區對 Chrome 的 HTTP 快取有何影響?
如果使用快取分區,系統在加密快取資源時,除了資源網址外,還會使用新的「網路隔離金鑰」。網路隔離金鑰由頂層網站和目前的頁框網站組成。
請再次查看上一個範例,瞭解快取分區在不同情況下的運作方式:
![快取金鑰 { https://a.example, https://a.example, https://x.example/doge.png}](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsexam-97fe4405170ee.png?authuser=6&hl=zh-tw)
https://a.example
, https://a.example
, https://x.example/doge.png
}
使用者造訪了網頁 (https://a.example
),而該網頁會要求圖片 (https://x.example/doge.png
)。在此情況下,系統會向網路要求圖片,並以元組 (包含 https://a.example
(頂層網站)、https://a.example
(目前頁框網站) 和 https://x.example/doge.png
(資源網址) 做為鍵來快取。(請注意,如果資源要求來自頂層頁框,則網路隔離金鑰中的頂層網站和目前頁框網站會相同)。
![快取金鑰 { https://a.example, https://a.example, https://x.example/doge.png}](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsexam-d34238052404.png?authuser=6&hl=zh-tw)
https://b.example
, https://b.example
, https://x.example/doge.png
}
同一使用者造訪了其他網頁 (https://b.example
),而該頁面要求相同的圖片 (https://x.example/doge.png
)。雖然在上一個範例中載入了同一張圖片,因為兩者並非在快取中找到了所需資料。
系統會從網路要求圖片,並使用由 https://b.example
、https://b.example
和 https://x.example/doge.png
做為鍵的元組進行快取。
![快取金鑰 { https://a.example, https://a.example, https://x.example/doge.png}](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsexam-b2b072114f1fc.png?authuser=6&hl=zh-tw)
https://a.example
, https://a.example
, https://x.example/doge.png
}
現在使用者返回 https://a.example
,但這次圖片 (https://x.example/doge.png
) 將嵌入 iframe 中。在本例中,鍵是包含 https://a.example
、https://a.example
和 https://x.example/doge.png
的元組,且會發生快取命中。(請注意,如果頂層網站和 iframe 是同一個網站,則可使用頂層頁框快取的資源)。
![快取金鑰 { https://a.example, https://a.example, https://x.example/doge.png}](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsexam-7f72d1a4803af.png?authuser=6&hl=zh-tw)
https://a.example
、https://c.example
、https://x.example/doge.png
}
使用者返回了 https://a.example
,但這次圖片託管在 https://c.example
的 iframe 中。
在這個案例中,圖片會從網路下載,因為快取中沒有任何資源與由 https://a.example
、https://c.example
和 https://x.example/doge.png
組成的金鑰相符。
![快取金鑰 { https://a.example, https://a.example, https://x.example/doge.png}](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsexam-bfba3d8b780d.png?authuser=6&hl=zh-tw)
https://a.example
、https://c.example
、https://x.example/doge.png
}
如果網域含有子網域或通訊埠號碼,該怎麼辦?使用者造訪 https://subdomain.a.example
,而該容器嵌入了 iframe (https://c.example:8080
),而後者會要求圖片。
由於金鑰是根據「scheme://eTLD+1」建立,因此會忽略子網域和通訊埠編號。導致快取命中。
![快取金鑰 { https://a.example, https://a.example, https://x.example/doge.png}](https://developer.chrome.google.cn/static/blog/http-cache-partitioning/image/cache-key-httpsexam-752e8576ec61f.png?authuser=6&hl=zh-tw)
https://a.example
、https://c.example
、https://x.example/doge.png
}
如果 iframe 經過巢狀結構多次,會發生什麼情況?使用者造訪 https://a.example
,其嵌入了 iframe (https://b.example
),而 iframe 則嵌入了另一個 iframe (https://c.example
),最後則要求圖片。
由於金鑰是從頂層頁框 (https://a.example
) 和載入資源的立即影格 (https://c.example
) 取得,因此快取命中才會發生。
常見問題
我的 Chrome 是否已啟用此功能?該如何確認?
這項功能將於 2020 年底推出。如何檢查您的 Chrome 執行個體是否已支援該執行個體:
- 開啟
chrome://net-export/
,然後按下「Start Logging to Disk」(開始記錄至磁碟)。 - 指定記錄檔在電腦上的儲存位置。
- 在 Chrome 上瀏覽網路一分鐘。
- 返回
chrome://net-export/
,然後按下「Stop Logging」。 - 前往
https://netlog-viewer.appspot.com/#import
。 - 按下「選擇檔案」,然後傳送已儲存的記錄檔。
系統會顯示記錄檔的輸出結果。
在同一個頁面上找出 SplitCacheByNetworkIsolationKey
。如果後方有 Experiment_[****]
,就表示 Chrome 已啟用 HTTP 快取分區。如果後方加上 Control_[****]
或 Default_[****]
,則不會啟用。
如何在 Chrome 上測試 HTTP 快取分區?
如要在 Chrome 上測試 HTTP 快取分區,您需要使用指令列標記 --enable-features=SplitCacheByNetworkIsolationKey
啟動 Chrome。請按照「使用標記執行 Chromium」一文中的操作說明,瞭解如何在平台上使用指令列標記啟動 Chrome。
身為網頁程式開發人員,我該採取什麼行動來因應這項異動?
這並非破壞性變更,但可能會提高某些網路服務的效能。
舉例來說,如果資源在許多網站上提供大量高快取資源 (例如字型和熱門指令碼),流量可能會增加。此外,使用這類服務的使用者可能更加依賴這些服務。
(其中一個提議以保護隱私的方式啟用共用程式庫,做法稱為網路共用資料庫 (展示影片),不過我們仍然在考慮此做法。)
這項行為變化會造成什麼影響?
整體快取失敗率增加約 3.6%、FCP (首次內容繪製) 的變更幅度適中 (約 0.3%),從網路載入的整體位元組比例也增加約 4%。如要進一步瞭解對效能的影響,請參閱 HTTP 快取分區說明。
內容是否已標準化?其他瀏覽器的運作方式是否不同?
「HTTP 快取分區」在擷取規格中標準化,但瀏覽器的做法有所不同:
- Chrome:使用頂層 scheme://eTLD+1 和 frame scheme://eTLD+1
- Safari:使用頂層 eTLD+1
- Firefox:規劃導入頂層 scheme://eTLD+1 並考慮納入第二個鍵 (例如 Chrome)
系統如何處理從工作站擷取的資料?
專屬工作站會使用與目前影格相同的金鑰。Service Worker 和共用工作站會因為多個頂層網站共用而比較複雜。相關解決方案目前正在討論中。