前端緩存
前端緩存可分為兩大類:HTTP 緩存和瀏覽器緩存。
我們今天重點是 HTTP 緩存,下面這張圖是前端緩存的一個大致知識點:
HTTP 緩存
首先解決困擾繞人們的老大難問題:
一、什么是HTTP緩存?
HTTP 緩存會存儲與請求關(guān)聯(lián)的響應(yīng),并將存儲的響應(yīng)復(fù)用于后續(xù)請求。(MDN)
通俗的講,HTTP 緩存指的是:當(dāng)瀏覽器向服務(wù)器發(fā)起資源請求時,會首先抵達(dá)瀏覽器緩存,如果瀏覽器有當(dāng)前請求資源的有效副本,就可以直接從瀏覽器緩存中取出資源并返回,不用再重新去服務(wù)器中獲取了。
常見的 HTTP 緩存只能緩存 GET 請求的資源,對于其他類型的響應(yīng)則無能為力,所以后續(xù)說的請求緩存都是指 GET 請求。
HTTP 緩存都是從第二次請求開始的,第一次請求資源時,服務(wù)器返回資源,并在 response headers 頭中回傳資源的緩存參數(shù);第二次請求時,瀏覽器會判斷這些參數(shù),命中強(qiáng)緩存就直接返回 200,否則就把緩存相關(guān)參數(shù)添加到 request headers 中傳給服務(wù)器,服務(wù)器判斷是否命中協(xié)商緩存,命中則返回 304,否則服務(wù)器會返回 200 并返回新的資源。
瀏覽器第一次請求流程圖:
注意: 官網(wǎng)文檔上用詞為 fresh 和 stale,國內(nèi)的文檔上大多都用詞為強(qiáng)緩存和協(xié)商緩存,此文也如此。
1. HTTP 緩存分類
根據(jù)是否需要向服務(wù)器重新發(fā)起請求來分類,可以分為強(qiáng)緩存和協(xié)商緩存;
注意: MDN上一般按照私有緩存和共有緩存來分來,但以上分類更適合于我們初學(xué)者了解緩存相關(guān)知識,所以本文按以上方式對緩存進(jìn)行分類!
下圖是強(qiáng)緩存和協(xié)商緩存的一些對比:
1.1 強(qiáng)緩存
強(qiáng)緩存是指在緩存數(shù)據(jù)未失效的情況下(即 Cache-Control
的 max-age
沒有過期或者 Expires
的緩存時間沒有過期),那么就會直接使用瀏覽器的緩存數(shù)據(jù),而不會請求服務(wù)器。
強(qiáng)緩存生效時,HTTP 狀態(tài)碼為 200。
優(yōu)點:這種方式頁面加載速度是最快的,性能也是很好的。
缺點:如果在這期間服務(wù)端資源有更新,頁面上是拿不到更新后的數(shù)據(jù)的。 這種情況我們在開發(fā)中也是經(jīng)常遇見的,比如我們修改了頁面的某個樣式,在頁面上刷新了但沒有生效,因為走的是強(qiáng)緩存,所以 Ctrl + F5 一頓操作過后就好了。
跟強(qiáng)緩存相關(guān)的 header 頭屬性有(Pragma / Cache-Control / Expires)
強(qiáng)緩存流程圖:
1.2 協(xié)商緩存
當(dāng)以下條件滿足一個或多個時:
- 當(dāng)?shù)谝淮握埱髸r,服務(wù)器返回的響應(yīng)頭中沒有設(shè)置 Cache-Control 和 Expires 字段;
- Cache-Control 和 Expires 過期;
- Cache-Control 和 Pragma 設(shè)置為:no-cache;
那么瀏覽器第二次請求時,就會與服務(wù)器進(jìn)行協(xié)商,與服務(wù)端對比判斷資源是否進(jìn)行了更新。
如果服務(wù)端資源未更新,則會返回 304 狀態(tài)碼,告訴瀏覽器當(dāng)前緩存可繼續(xù)使用;如果服務(wù)端資源有更新,則會返回 200 狀態(tài)碼,并同時返回更新后的資源和緩存信息字段。
與協(xié)商緩存相關(guān)的字段有 ETag / If-None-Match、Last-Modified / If-Modified-Since,此時請求頭與響應(yīng)頭需要成對出現(xiàn)。
協(xié)商緩存流程示意圖如下:
二、如何使用 HTTP 緩存?
一般需要緩存的資源有 HTML 頁面和其他一些靜態(tài)資源:
-
HTML 頁面緩存的設(shè)置主要是在 <head> 標(biāo)簽中嵌入 <meta> 字段,這種方式只對頁面有效,對頁面上的資源無效。
1.1 HTML 頁面禁用緩存的設(shè)置如下:
<meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0">
2.2 HTML 設(shè)置使用緩存如下:
<meta http-equiv="Cache-Control" content="max-age=7200" /> <meta http-equiv="Expires" content="Mon, 20 Aug 2018 23:00:00 GMT" />
-
靜態(tài)資源的緩存一般是在web服務(wù)器上配置的,常用的web服務(wù)器有:nginx、apache。具體的配置這里不做詳細(xì)介紹,大家自行查閱。
三、HTTP 緩存的幾個注意點
-
強(qiáng)緩存情況下,只要緩存還沒過期,就會直接從緩存中讀取數(shù)據(jù),就算服務(wù)端有變化,也不會從服務(wù)端獲取更新后的數(shù)據(jù),這就就會導(dǎo)致無法獲取到最新的數(shù)據(jù)。
解決的辦法有:在修改后的資源加上隨機(jī)數(shù),確保不會從緩存中讀取。
例如:
http://www.example.com/common.css?v=110
http://www.example.com/common.111.css -
盡量減少 304 的請求,因為我們知道,協(xié)商緩存每次都會與后臺服務(wù)器進(jìn)行交互,所以性能上不是很好,從性能上來看盡量多使用強(qiáng)緩存。
-
在 Firefox 瀏覽器上,使用 Cache-Control: no-cache 是不生效的,其識別的是 no-store。這樣能達(dá)到其他瀏覽器使用 Cache-Control: no-cache 的效果,所以為了兼容 Firefox 瀏覽器,經(jīng)常會寫成 Cache-Control: no-cache, no-store。
-
與緩存相關(guān)的幾個 header 屬性:Vary、Date / Age。
Vary:
Vary 本身是“變化”的意思,而在 HTTP 報文中更趨于是“vary from”(與。。。不同)的含義,它表示服務(wù)端會以什么基準(zhǔn)字段來區(qū)分、篩選緩存版本。在服務(wù)端有著這么一個地址,如果是 IE 用戶則返回針對 IE 開發(fā)的內(nèi)容,否則返回另一個主流瀏覽器版本的內(nèi)容。
格式:Vary: User-Agent
知會代理服務(wù)器需要以 User-Agent 這個請求首部字段來區(qū)分緩存版本,防止傳遞給客戶端的緩存不正確。
Date / Age:
響應(yīng)報文中的 Date 和 Age 字段:區(qū)分其收到的資源是否命中了代理服務(wù)器的緩存。
Date 理所當(dāng)然是原服務(wù)器發(fā)送該資源響應(yīng)報文的時間(GMT格式),如果你發(fā)現(xiàn) Date 的時間與“當(dāng)前時間”差別較大,或者連續(xù)F5刷新發(fā)現(xiàn) Date 的值都沒變化,則說明你當(dāng)前請求是命中了代理服務(wù)器的緩存。文章來源:http://www.zghlxwxcb.cn/news/detail-459088.html
Age 也是響應(yīng)報文中的首部字段,它表示該文件在代理服務(wù)器中存在的時間(秒),如文件被修改或替換,Age會重新由0開始累計。文章來源地址http://www.zghlxwxcb.cn/news/detail-459088.html
到了這里,關(guān)于前端性能優(yōu)化之HTTP緩存的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!