天天看點

http緩存

前端緩存可分為兩大類:http緩存和浏覽器緩存。我們今天重點講的是http緩存,是以關于浏覽器緩存大家自行去查閱。下面這張圖是前端緩存的一個大緻知識點:

http緩存

1.什麼是HTTP緩存(原理)?

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

2.緩存的作用

我們為什麼使用緩存,是因為緩存可以給我們的 Web 項目帶來以下好處,以提高性能和使用者體驗。

  • 加快了浏覽器加載網頁的速度;
  • 減少了備援的資料傳輸,節省網絡流量和帶寬;
  • 減少伺服器的負擔,大大提高了網站的性能

3.http緩存分類

3.1緩存的規則

我們知道HTTP的緩存屬于用戶端緩存,後面會提到為什麼屬于用戶端緩存。是以我們認為浏覽器存在一個緩存資料庫,用于儲存一些不經常變化的靜态檔案(圖檔、css、js等)。我們将緩存分為強制緩存和協商緩存。下面我将分别詳細的介紹這兩種緩存的緩存規則。

為了友善了解,我們認為浏覽器存在一個緩存資料庫,用于存儲緩存資訊(實際上靜态資源是被緩存到了記憶體和磁盤中),在浏覽器第一次請求資料時,此時緩存資料庫沒有對應的緩存資料,則需要請求伺服器,伺服器會将緩存規則和資料傳回,浏覽器将緩存規則和資料存儲進緩存資料庫。

3.1.1 get和post差別的緩存問題

http緩存目的就是使應用執行的更快,更易擴充,但是http緩存通常隻适用于idempotent request - 幂等性(可以了解為查詢請求,也就是不更新服務端資料的請求),這也就導緻了在http的世界裡,一般都是對get請求做緩存,post請求很少有緩存。

get多用來直接擷取資料,不修改資料,主要目的就是db的search語句的感覺。用緩存(有個代理伺服器的概念)的目的就是查db的速度變快。

post則是發送資料到伺服器端去存儲。類似db裡的update delete和insert語句的感覺。更新db的意思。資料必須放在資料庫,是以一般都得去通路伺服器端。

http緩存

根據是否需要重新向伺服器發起請求來分類,可分為:強制緩存、協商緩存。在詳細介紹這兩種規則之前,先通過時序圖的方式,讓大家對這兩種規則有個簡單了解。

3.2強制緩存

已存在緩存資料時,僅基于強制緩存,請求資料的流程如下:

http緩存

對于強制緩存,伺服器響應的header中會用兩個字段來表明——Expires和Cache-Control。

Expires:

Expires此字段為http1.0推出的,代表着是緩存過期的時間,如果用戶端的時間大于此時間就代表緩存過期,要去服務端擷取資料并且重新整理此字段的時間。不過由于用戶端時間和伺服器的時間是有差異的,是以緩存命中也有誤差。是以推出了Cache-Control字段來替代,不過因為有時為了相容1.0,是以有時還會使用Expires字段。

Cache-Control:

Cache-Control 該字段表示緩存最大有效時間,該時間是一個相對時間。

使用相對時間的話,即使本地時間與伺服器時間不一緻,也不會導緻緩存失效。常見的取值有private、public、no-cache、max-age、no-store,預設為private。

http緩存

no-cache:如果request headers中,Cache-Control為no-cache。表示不管服務端有沒有設定Cache-Control,都必須從重新去擷取請求。

max-age=0:max-age=0表示不管response怎麼設定,在重新擷取資源之前,先檢驗ETag/Last-Modified。

不管是max-age=0還是no-cache,都會傳回304(資源無修改的情況下),no-store才是真正的不進行緩存

http緩存

圖中Cache-Control僅指定了max-age,是以預設為private,緩存時間為31536000秒(365天)也就是說,在365天内再次請求這條資料,都會直接擷取緩存資料庫中的資料,直接使用。

3.2.1通過Network檢視強制緩存

我們通過 Chrome 浏覽器的開發者工具,打開 NetWork 檢視強制緩存的相關資訊。

http緩存

上面是百度網站Logo圖檔的響應,我們可以清楚的看到,其中相容了HTTP 1.0和HTTP1.1版本,并使用強制緩存存儲了10年。

下面看一看通過緩存取出的資料在 Network 中與其他資源的差別。

http緩存

其實緩存的儲存是記憶體和磁盤兩個位置,由目前浏覽器本身的政策決定,比較随機,從記憶體的緩存中取出的資料會顯示 (from memory cache),從磁盤的緩存中取出的資料會顯示(from disk cache)。

3.2.2 memory cache 和 disk cache 緩存

memory cache: 它是将資源檔案緩存到記憶體中。等下次請求通路的時候不需要重新下載下傳資源,而是直接從記憶體中讀取資料。

disk cache: 它是将資源檔案緩存到硬碟中。等下次請求的時候它是直接從硬碟中讀取。

那麼他們兩則的差別是?

memory cache(記憶體緩存)退出程序時資料會被清除。

disk cache(硬碟緩存)退出程序時資料不會被清除。記憶體讀取比硬碟中讀取的速度更快。但是我們也不能把所有資料放在記憶體中緩存的,因為記憶體也是有限的。

memory cache(記憶體緩存)一般會将腳本、字型、圖檔會存儲到記憶體緩存中。

disk cache(硬碟緩存) 一般非腳本會存放在硬碟中,比如css這些。

其實很簡單,隻要頁面在網頁上打開通路,然後不關閉,重新整理一定是from memory cache,而頁面關閉在打開一定是from dick cache。這就是浏覽器自身的緩存手段,磁盤緩存一定會有一份備份的,然後頁面通路的時候也會在記憶體中緩存一份,這樣重新整理目前頁面就不會讀取硬碟,而是直接從記憶體中讀取(減少通路盤符的次數)。

不同浏覽器的一些表現差異:

不同的浏覽器的緩存手段是一緻的,但是文案展示形式,和重新整理頁面的方式會有差異(如火狐浏覽器點選重新整理按鈕和回車重新整理是不一樣的)。

下面是針對已經強緩存,同時通路檔案無修改的情況下,不同重新整理方式傳回的狀态碼總結:

http緩存

3.3協商緩存

協商緩存,顧名思義,需要進行比較判斷是否可以使用緩存。

已存在緩存資料時,僅基于對比緩存,請求資料的流程如下

http緩存

浏覽器第一次請求資料時,伺服器會将緩存辨別與資料一起傳回給用戶端,用戶端将二者備份至緩存資料庫中。

再次請求資料時,用戶端将備份的緩存辨別發送給伺服器,伺服器根據緩存辨別進行判斷,判斷成功後,傳回304狀态碼,通知用戶端比較成功,可以使用緩存資料。

第一次通路:

http緩存

再次通路:

http緩存

通過兩圖的對比,我們可以很清楚的發現,在對比緩存生效時,狀态碼為304,并且封包大小和請求時間大大減少。

原因是,服務端在進行辨別比較後,隻傳回header部分,通過狀态碼通知用戶端使用緩存,不再需要将封包主體部分傳回給用戶端。

對于對比緩存來說,緩存辨別的傳遞是我們着重需要了解的,它在請求header和響應header間進行傳遞,一共分為兩種辨別傳遞,接下來,我們分開介紹。

Last-Modified / If-Modified-Since

Last-Modified:

伺服器在響應請求時,告訴浏覽器資源的最後修改時間:

http緩存

If-Modified-Since:

再次請求伺服器時,通過此字段通知伺服器上次請求時,伺服器傳回的資源最後修改時間。

伺服器收到請求後發現有頭If-Modified-Since 則與被請求資源的最後修改時間進行比對。

若資源的最後修改時間大于If-Modified-Since,說明資源又被改動過,

則響應整片資源内容,傳回狀态碼200;

若資源的最後修改時間小于或等于If-Modified-Since,說明資源

無新修改,則響應HTTP 304,告知浏覽器繼續使用所儲存的cache。

http緩存

Last-Modified & if-modified-since流程圖:

Etag / If-None-Match(優先級高于Last-Modified / If-Modified-Since):

Etag:

伺服器響應請求時,告訴浏覽器目前資源在伺服器的唯一辨別(生成規則由伺服器決定)。

http緩存

If-None-Match:

再次請求伺服器時,通過此字段通知伺服器客戶段緩存資料的唯一辨別。

伺服器收到請求後發現有頭If-None-Match 則與被請求資源的唯一辨別進行比對,不同,說明資源又被改動過,則響應整片資源内容,傳回狀态碼200;

相同,說明資源無新修改,則響應HTTP 304,告知浏覽器繼續使用所儲存的cache。

3.3.1為什麼既有Last-Modified還有Etag(兩者并存,有什麼好處)

使用Last-Modified已經足以讓浏覽器知道本地的緩存副本是否足夠新,為什麼還需要Etag呢?HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題:

  • 一些檔案也許會周期性的更改,但是他的内容并不改變(僅僅改變的修改時間),這個時候我們并不希望用戶端認為這個檔案被修改了,而重新GET;
  • 某些檔案修改非常頻繁,比如在秒以下的時間内進行修改,(比方說1s内修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME隻能精确到秒);
  • 某些伺服器不能精确的得到檔案的最後修改時間。

這時,利用Etag能夠更加準确的控制緩存,因為Etag是伺服器自動生成或者由開發者生成的對應資源在伺服器端的唯一辨別符。

Last-Modified與ETag是可以一起使用的,伺服器會優先驗證ETag,一緻的情況下,才會繼續比對Last-Modified,最後才決定是否傳回304。

3.4兩類緩存同時存在

兩類緩存規則可以同時存在,強制緩存優先級高于對比緩存,也就是說,當執行強制緩存的規則時,如果緩存生效,直接使用緩存,不再執行對比緩存規則。

3.5強制/協商緩存的對比

http緩存
`浏覽器第一次請求`           
浏覽器第二次請求           

繼續閱讀