在前端開發中,快取有利於加快網頁的載入速度,同時快取能夠被反覆利用,所以可以減少流量和頻寬的開銷。瀏覽器的快取問題,主要指的是http的快取——即協議層。而h5新增的storage和資料庫快取,那是應用層快取,並不被計入本篇的分析內容裡面。下面我們正式開始來進行快取的分析。
協議層的快取,其實,可以被分成強制快取和對比快取。
首先,我們先來看一張強制快取時的時序圖,來了解一下強制快取在不同情況下的請求模式:
從圖中,我們不難看出,只有當快取失效時,才會去伺服器獲取最新資源的方式,就是強制快取。而在協議層的字段中,可以造成強制快取的字段有兩個expires和cache-control。
最早使用的是expires欄位,該欄位表示快取到期時間,即有效時間+當時伺服器的時間,然後將這個時間設定在header中返回給伺服器。因此,該時間是乙個絕對時間,舉例說明:
expires: thu, 10 nov 2017 08:45:11 gmt
![expires](
在響應訊息頭中,設定這個字段之後,就可以告訴瀏覽器,在未過期之前不需要再次請求。
但是,這個字段設定時有缺點:
由於是絕對時間,使用者可能會將客戶端本地的時間進行修改,而導致瀏覽器判斷快取失效,重新請求該資源,同時,還導致客戶端與服務端的時間不一致,致使快取失效。
已知expires的缺點之後,在http/1.1中,增加了乙個欄位cache-control,該欄位表示資源快取的最大有效時間,在該時間內,客戶端不需要向伺服器傳送請求
這兩者的區別就是前者是絕對時間,而後者是相對時間。我們不妨舉個例子來說明一下:
cache-control: max-age=2592000
下面列舉一下cache-control的字段可以帶的值:
max-age:即最大有效時間,在上面的例子中我們可以看到
no-cache:表示沒有快取,即告訴瀏覽器該資源並沒有設定快取
s-maxage:同max-age,但是僅用於共享快取,如cdn快取
public:多使用者共享快取,預設設定
private:不能夠多使用者共享,http認證之後,欄位會自動轉換成private。
總結一下,自從http1.1開始,expires逐漸被cache-control取代。cache-control是乙個相對時間,即使客戶端時間發生改變,相對時間也不會隨之改變,這樣可以保持伺服器和客戶端的時間一致性。而且cache-control的可配置性比較強大。
扯完強制快取,我們來看看對比快取。在解釋這個之前,是否可以先猜想一下,強制快取是,快取在未過有效期時,不需要請求資源。那麼,對比快取的原理又該如何呢?
廢話不多說,我們也先從對比快取的時序圖講起,如圖:
對比快取的過程是,先從快取中獲取對應的資料標識,然後向伺服器傳送請求,確認資料是否更新,如果更新,則返回新資料和新快取;反之,則返回304狀態碼,告知客戶端快取未更新,可繼續使用。
這正好彌補了一些強制快取的缺陷。對比快取主要應用於一些時常需要動態更新的資源檔案。
對比快取在協議裡的字段是last-modified和if-modified-since。
last-modified:伺服器告知客戶端,資源最後一次被修改的時間,例如
last-modified: thu, 10 nov 2015 08:45:11 gmt
if-modified-since:再次請求時,請求頭中帶有該欄位,伺服器會將if-modified-since的值與last-modified欄位進行對比,如果相等,則表示未修改,響應304;反之,則表示修改了,響應200狀態碼,返回資料。
這個字段可以和cache-control配合使用。
但是他還是有一定缺陷的:
如果資源更新的速度是秒以下單位,那麼該快取是不能被使用的,因為它的時間單位最低是秒。
如果檔案是通過伺服器動態生成的,那麼該方法的更新時間永遠是生成的時間,儘管檔案可能沒有變化,所以起不到快取的作用。
由於last-modified還是存在缺陷的,儘管大多數情況下,會使用它,但當遇到我們上面所說的場景時,我們可能就需要了解一下,我們另乙個小夥伴了——etag。
etag儲存的是檔案的特殊標識(一般都是hash生成的),伺服器儲存著檔案的etag欄位,可以在與每次客戶端傳送if-no-match的字段進行比較,如果相等,則表示未修改,響應304;反之,則表示已修改,響應200狀態碼,返回資料。
最後,通過一張原理圖,我們來加深一下記憶:
至此為止,兩種快取型別的快取方式已經闡述完成了,不知你是否已經心中已經有個大致的印象,當別人問起時,你可以對答如流。希望我們一同進步吧,fighting。
最後,我們來聊聊瀏覽器行為會引起快取的變化吧。
下面說一下瀏覽器的行為會產生怎樣的請求:
重新整理網頁 => 如果快取沒有失效,瀏覽器會直接使用快取;反之,則向伺服器請求資料
手動重新整理(f5) => 瀏覽器會認為快取失效,在請求伺服器時加上cache-control: max-age=0欄位,然後詢問伺服器資料是否更新。
強制重新整理(ctrl + f5) => 瀏覽器會直接忽略快取,在請求伺服器時加上cache-control: no-cache欄位,然後重新向伺服器拉取檔案。
在pc端或許這樣子的快取機制就已經足夠了,因為pc端不需要為網路的問題擔心。
但是,移動端卻不行,任何乙個網路請求的增加,對於移動端的載入消耗時間都是比較大的(誰叫移動端的網太差呢,3g、2g)。那麼,上述的快取有什麼問題呢?其實,強制快取是沒有太大問題的,因為只要快取不到期,是不會想伺服器傳送請求的;但是如果是對比快取的情況下,304的問題就比較巨大,因為它會造成無用的請求。每次在使用快取前,都會向伺服器傳送請求確認,導致網路的延時。
一次完美的快取必須保證兩點:
1. 資料快取之後,儘量減少伺服器的請求
2. 如果資源更新的話,必須使得客戶端的資源一起更新。
所以,一般我們會運用的方式是:
在資源檔案後面加上表示,如config.f1ec3.js、config.v1.js之類的,然後給資源設定較長的快取時間,如一年
cache-control: max-age=31536000
這樣子,就不會造成304的回包現象。
然後一旦資源發生更新時,我們可以改變資源後面的識別符號,實現靜態資源非覆蓋式更新。
本篇大致分析了瀏覽器快取部分的分類情況,以及細化分析。主要可分為:
1. 強制快取
Nginx瀏覽器快取篇
環境 centos7 nginx 1.16.0 expires原理 給http新增cache control expires頭 expires指令控制http應答中的 expires 和 cache control header頭部資訊,啟動控制頁面快取的作用 time 可以使用正數或負數。expi...
瀏覽器快取總結篇
瀏覽器快取策略大家一定不陌生,如果沒有進行系統的歸納總結,可能三言兩語說不清楚。這點我在面試中感觸頗深,以前未經過深入理解時,只能說出幾個概念或者回答得比較模糊,甚至說錯,顯得自己的基礎知識特別不紮實。瀏覽器快取介紹 快取機制 原理 快取分類 協商快取 快取位置 下面是我做的乙個大致的思維導圖 1....
快取 瀏覽器快取
瀏覽器快取 brower caching 是瀏覽器在本地磁碟對使用者最近請求過的文件進行儲存,當訪問者再次訪問同一頁面時,瀏覽器就可以直接從本地磁碟載入文件 1 瀏覽器第一次請求時,會發出一組 http 頭,用來指導瀏覽器如何進行快取。伺服器規定乙個資源是否要進行快取,主要由響應頭中的expires...