人盡皆知的HTTP快取,你真的能說清?

2021-10-07 01:49:49 字數 4057 閱讀 5990

快取的應用非常廣泛,在前端更是有著舉足輕重的地位,是解決效能問題最常用的手段之一。

加快網頁載入和呈現速度。

減少了不必要的的請求,因而節省網路流量和頻寬同時也減少伺服器的負擔。

本文要詳細說的是 http 快取。

http 快取指的是: 當客戶端向伺服器請求資源時,會先抵達瀏覽器快取,如果瀏覽器有「要請求資源」的副本,就可以直接從瀏覽器快取中提取而不是從原始伺服器中提取這個資源。

常見的http快取只能快取get請求響應的資源,對於其他型別的響應則無能為力,所以後續說的請求快取都是指get請求。

資源快取分為兩類:from disk cache(磁碟)和from memory cache(記憶體) 。

from disk cachefrom memory cache是如何搭配工作的呢 ?

當使用者首次訪問網頁時,資源檔案被快取在記憶體中,同時也會在本地磁碟中保留乙份副本。

當使用者重新整理頁面,如果快取的資源沒有過期,那麼直接從記憶體中讀取並載入。當使用者關閉頁面後,當前頁面快取在記憶體中的資源被清空。

當使用者再一次訪問頁面時,如果資源檔案的快取沒有過期,那麼將從本地磁碟進行載入並再次快取到記憶體之中

需要注意的是雖然資源被同時儲存在記憶體和磁碟快取中,但是絕大部分瀏覽器都會優先使用記憶體快取, 因為讀取記憶體快取的速度更快。儲存再磁碟快取的目的是防止瀏覽器崩潰或者主動退出,因為磁碟快取是持久的。

當然快取也存在有效期,我們稱之為快取的失效策略,如果以此分類,又分為:

理解快取的策略是學習快取的核心,下面分別介紹兩種策略。

強快取是指客戶端在第一次請求後,將得到的資料進行快取,有效時間內不會再去請求伺服器,而是直接使用快取資料。所有的資料都不是永恆不變的,到底什麼時候再次重新請求呢?那麼這個過程,就涉及到乙個快取有效期的判斷。http 1.0 和 http 1.1 在判斷邏輯上是有差異的。

http 1.0 版本:規定響應頭欄位 expires,它對應乙個未來的時間戳。客戶端第一次請求之後,服務端下發 expires 響應頭欄位,當客戶端再次需要請求時,先會對比當前時間和 expires 頭中設定的時間。如果當前時間早於 expires 時間,那麼直接使用快取資料。反之,需要再次傳送請求,更新資料。

響應頭如:

// response headers

expires: wed,

10 june 202015:

32:12gmt

上述 expires 資訊告訴瀏覽器:在2023年6月10號15點32分12秒之前,可以直接使用快取不用請求資料。

注意: expires 響應頭的方式對伺服器端和客戶端有時間的要求, 時間必須一致, 並且expires 響應頭對格式要求非常嚴格。

http 1.1 版本:服務端使用更加強大的 cache-control 響應頭,它具有多個配置值:

我們看這樣的 cache-control 設定:

// response headers

cache-control:

private

, max-age=

3600

, must-revalidate

它表示:該資源只能被瀏覽器快取。max-age=3600 說明該快取資源3600秒後過期。

注意:http 規定,如果 cache-control 的 max-age 和 expires 同時出現,那麼 max-age 的優先順序更高,他會預設覆蓋掉 expires 。

強快取判斷的實質上是快取資源是否超出某個時間或者某個時間段。但問題是很多情況是超出了這個時間或時間段,但是資源並沒有更新。但是還是要發起一次請求去請求沒有改變的資料或資源。

從優化的角度來說,有些情況下我們真正應該關心的是伺服器端檔案是否已經發生了變化,如果改變了我們再去請求而不是一貫的遵循時間規定。此時我們需要用到協商快取策略。

那麼問題來了,如何知道伺服器端檔案是否已經發生改變了呢?

強快取關於是否使用快取完全是由瀏覽器決定的,想讓瀏覽器自己知道伺服器端檔案是否已經發生了變化是不可能的。

那麼使用協商快取時否是使用快取的決定權必然要交給服務端,因此協商快取不可避免的要發起一次網路請求。

協商快取過程:在瀏覽器端,當對某個資源的請求不採取強快取策略時(第一次請求伺服器返回的響應頭沒有 cache-control 和 expires 或者 cache-control 和 expires 過期再或者它的屬性設定為 no-cache),瀏覽器就會發乙個請求到伺服器,驗證是否採取協商快取策略,如果採取協商快取,請求響應返回的 http 狀態就為 304。

服務端如何判斷資源有沒有過期?

服務端掌握著最新的資源,那麼為了做對比,它需要知道客戶端的資源資訊。根據 http 協議,通過【etag、if-none-match】和【last-modified,if-modified-since】這兩對 header 來作出決定。

【last-modified,if-modified-since】 這一對 header 主導的協商快取過程:

但是這種協商快取的策略依然存在強快取策略中的問題,就是如果客戶端時間不准就會導致時間驗證出現問題,並且一些檔案也許會週期性的更改,但是他的內容並不改變,僅僅改變的修改時間。並且 last-modified 標註的最後修改只能精確到秒,如果某些檔案在1秒鐘以內,被修改多次的話,它將不能準確標註檔案的修改時間。這些情況下使用 last-modified 就不是很適合了。

為了解決這個問題,就有了 【etag、if-none-match】這一對 header 頭來進行協商快取的判斷。

【etag、if-none-match】這一對 header 主導的協商快取過程:

response headers: etag: "55d7b35d71da3051f63ab95f9608f821
etag 的生成策略,實際上並沒有強制的規範,這就取決於各大廠商或平台的自主實現方式了。

另外需要注意的細節是:

當我們在瀏覽器進行操作的時候何時會觸發快取行為呢?

由於瀏覽器引擎的差異,快取行為的表現可能會略有差異,以 chrome 為例:

2. 當進行 f5 重新整理時跳過強快取,但是協商快取仍然有效。

3. 當使用 ctrl + f5 進行強制重新整理時,強快取和協商快取均失效。

一般需要快取的資源有html頁面和其他靜態資源:

html頁面快取的設定主要是在標籤中嵌入標籤,這種方式只對頁面有效,對頁面上的資源無效

1.1. html頁面禁用快取的設定如下:

主流瀏覽器可識別的標籤

1.2. html設定快取如下:

主流瀏覽器識別的標籤

僅有ie瀏覽器識別的標籤

靜態資源的快取一般是在web伺服器上配置的。

各種快取策略在優先順序上:cache-control > expires > etag > last-modified

對於快取的使用我們可以大體的遵循以下兩條原則:

強制快取優先順序最高,並且無論資源是否改動在快取有效期內瀏覽器都不會傳送請求,因此強快取的使用適用於大型且不易修改的的資源檔案,例如第三方 css、js 檔案或資源。

協商快取靈活性高,適用於資料的快取,並且 etag 的靈活性更高。

你真的了解Http協議麼

網際網路就是具有通訊和線路功能而位置不同的多個計算機的一種 簡稱萬物互聯 https和http區別http協議與其說是協議 不如說是規定 通過瀏覽器和伺服器進行資料互動,進行超文字傳輸 底層就是tcp ip 所以get和post的底層也是tcp ip,也就是說,get post都是tcp鏈結。get...

關於Http和Https你真的搞懂了麼?

你可能熟悉url的https和http部分。它是fqdn的第一部分或url 例如中的url 你可能會注意到某些 使用https,而另一些 則使用http。http和https都負責提供乙個通道,可以在該通道中在裝置和web伺服器之間傳輸資料,從而可以進行正常的web瀏覽功能。http和https之間...

http學習 http的快取控制

由於請求 應答模式的通訊成本比較高,所以有必要將某些資料進行快取,從而節省頻寬。快取是優化系統效能的重要手段,http 傳輸的每乙個環節中都可以有快取 2.1 快取控制的流程 瀏覽器發現快取無資料,於是傳送請求,向伺服器獲取資源 伺服器響應請求,返回資源,同時標記資源的有效期 瀏覽器快取資源,等待下...