?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
通過重復(fù)使用先前提取的資源,可以顯著提高網(wǎng)站和應(yīng)用程序的性能。Web緩存減少了延遲和網(wǎng)絡(luò)流量,從而減少了顯示資源表示所需的時(shí)間。通過使用HTTP緩存,網(wǎng)站變得更加快速響應(yīng)。
緩存是一種技術(shù),可存儲給定資源的副本,并在請求時(shí)將其返回。當(dāng)Web緩存在其存儲中具有請求的資源時(shí),它攔截該請求并返回其副本,而不是從原始服務(wù)器重新下載。這實(shí)現(xiàn)了幾個(gè)目標(biāo):它減輕了不需要為所有客戶端服務(wù)的服務(wù)器的負(fù)載,并且通過更接近客戶端來提高性能,即,將資源傳回的時(shí)間更短。對于一個(gè)網(wǎng)站來說,它是實(shí)現(xiàn)高性能的一個(gè)重要組成部分。另一方面,它必須正確配置,因?yàn)椴⒎撬匈Y源都永遠(yuǎn)保持一致:僅在資源緩存更改時(shí)才緩存資源,這一點(diǎn)非常重要。
有幾種緩存:這些緩存可以分為兩大類:私有緩存或共享緩存。甲共享高速緩存是由一個(gè)以上的用戶存儲用于重用響應(yīng)的高速緩存中。一個(gè)私有緩存專用于單個(gè)用戶。該頁面主要討論瀏覽器和代理緩存,但也有部署在Web服務(wù)器上的網(wǎng)關(guān)緩存,CDN,反向代理緩存和負(fù)載平衡器,以提高網(wǎng)站和Web應(yīng)用程序的可靠性,性能和擴(kuò)展性。
專用緩存專用于單個(gè)用戶。您可能已經(jīng)在瀏覽器的設(shè)置中看到“緩存”。瀏覽器緩存保存用戶通過HTTP下載的所有文檔。該緩存用于使訪問文檔可用于后退/前進(jìn)導(dǎo)航,保存,以源代碼查看等,而無需額外訪問服務(wù)器。它同樣改進(jìn)了緩存內(nèi)容的離線瀏覽。
共享緩存是一個(gè)緩存,用于存儲將被多個(gè)用戶重用的響應(yīng)。例如,ISP或貴公司可能已將Web代理設(shè)置為其本地網(wǎng)絡(luò)基礎(chǔ)架構(gòu)的一部分,以便為許多用戶提供服務(wù),從而使常用資源多次重復(fù)使用,從而減少網(wǎng)絡(luò)流量和延遲。
HTTP緩存是可選的,但通常需要重新使用緩存資源。但是,常見的HTTP緩存通常僅限于緩存響應(yīng)GET
并可能拒絕其他方法。主緩存鍵由請求方法和目標(biāo)URI組成(通常只有URI被使用,因?yàn)橹挥蠫ET請求才是緩存目標(biāo))。常見的緩存條目形式是:
檢索請求的成功結(jié)果:200
對GET
包含諸如HTML文檔,圖像或文件等資源的請求的(確定)響應(yīng)。
永久重定向:a 301
(永久移動(dòng))響應(yīng)。
錯(cuò)誤響應(yīng):一個(gè)404
(未找到)結(jié)果頁面。
不完整的結(jié)果:(206
部分內(nèi)容)響應(yīng)。
除了GET
定義適合用作緩存鍵的東西之外的其他響應(yīng)。
如果請求是內(nèi)容協(xié)商的目標(biāo),則高速緩存條目也可能由多個(gè)由輔助鍵區(qū)分的存儲響應(yīng)組成。有關(guān)更多詳細(xì)信息,請參閱Vary
下面的標(biāo)題信息。
Cache-control
頭Cache-Control
HTTP / 1.1通用頭字段用于指定在請求和響應(yīng)緩存機(jī)制的指令。使用這個(gè)頭文件可以用它提供的各種指令來定義你的緩存策略。
緩存不應(yīng)該存儲有關(guān)客戶端請求或服務(wù)器響應(yīng)的任何內(nèi)容。一個(gè)請求被發(fā)送到服務(wù)器,并且每次都會(huì)下載一個(gè)完整的響應(yīng)。
Cache-Control: no-store Cache-Control: no-cache, no-store, must-revalidate
在釋放緩存副本之前,緩存會(huì)將請求發(fā)送到原始服務(wù)器進(jìn)行驗(yàn)證。
Cache-Control: no-cache
“public”指令表明響應(yīng)可能被任何緩存緩存。如果頁面具有HTTP身份驗(yàn)證或響應(yīng)狀態(tài)代碼通常不可緩存的頁面現(xiàn)在應(yīng)該被緩存,這可能很有用。另一方面,“私有”表示該響應(yīng)僅適用于單個(gè)用戶,并且不得由共享緩存存儲。在這種情況下,私人瀏覽器緩存可能會(huì)存儲響應(yīng)。
Cache-Control: privateCache-Control: public
這里最重要的指令是“ max-age=<seconds>
”,這是資源被認(rèn)為是最新的最大時(shí)間量。相反Expires
,這個(gè)指令是相對于請求的時(shí)間而言的。對于應(yīng)用程序中不會(huì)更改的文件,通常可以添加積極的緩存。這包括靜態(tài)文件,例如圖像,CSS文件和JavaScript文件。
有關(guān)更多詳細(xì)信息,另請參閱下面的“新鮮度”部分。
Cache-Control: max-age=31536000
使用“ must-revalidate
”指令時(shí),緩存必須在使用前驗(yàn)證陳舊資源的狀態(tài),不應(yīng)使用過期資源。有關(guān)更多詳細(xì)信息,請參閱下面的驗(yàn)證部分。
Cache-Control: must-revalidate
Pragma
頭Pragma
是一個(gè)HTTP / 1.0標(biāo)頭,它是未指定的HTTP響應(yīng),因此不為普通HTTP / 1.1的可靠替換Cache-Control
首部,雖然它不表現(xiàn)一樣Cache-Control: no-cache
,如果Cache-Control
在請求中省略報(bào)頭字段。使用Pragma
僅適用于HTTP / 1.0客戶端的向后兼容性。
一旦資源存儲在緩存中,理論上它可以永久存儲在緩存中。緩存具有有限的存儲空間,因此項(xiàng)目會(huì)定期從存儲中刪除。這個(gè)過程被稱為緩存逐出。另一方面,服務(wù)器上的一些資源可能會(huì)發(fā)生變化,所以應(yīng)該更新緩存。由于HTTP是客戶端 - 服務(wù)器協(xié)議,因此當(dāng)資源發(fā)生更改時(shí),服務(wù)器無法聯(lián)系緩存和客戶端; 他們必須傳達(dá)資源的到期時(shí)間。在這個(gè)到期時(shí)間之前,資源是新鮮的 ; 到期后,資源已過時(shí)。驅(qū)逐算法經(jīng)常使新資源超過陳舊的資源。請注意,陳舊的資源不會(huì)被驅(qū)逐或忽略; 當(dāng)緩存接收到過時(shí)資源的請求時(shí),它會(huì)將此請求轉(zhuǎn)發(fā)給a,If-None-Match
以檢查它是否實(shí)際上仍然是新的。如果是這樣,服務(wù)器返回304
(未修改)標(biāo)題,而不發(fā)送請求資源的主體,節(jié)省一些帶寬。
以下是使用共享高速緩存代理的此過程示例:
更新度使用壽命是根據(jù)多個(gè)標(biāo)題計(jì)算得出的。如果Cache-control: max-age=N
指定了“ ”標(biāo)題,則新鮮度生存期等于N.如果該標(biāo)題不存在(通常是這種情況),則檢查Expires
標(biāo)題是否存在。如果Expires
存在標(biāo)題,則其值減去Date
標(biāo)題的值確定新鮮度生存期。最后,如果兩個(gè)標(biāo)題都不存在,請查找Last-Modified
標(biāo)題。如果存在這個(gè)頭部,則緩存的新鮮度壽命等于Date
頭部的值減去頭部的值Last-modified
除以10。
到期時(shí)間計(jì)算如下:
expirationTime = responseTime + freshnessLifetime - currentAge
responseTime
根據(jù)瀏覽器收到響應(yīng)的時(shí)間在哪個(gè)位置?
我們使用緩存資源越多,網(wǎng)站的響應(yīng)能力和性能就越好。為了優(yōu)化這一點(diǎn),良好的做法建議盡可能在將來設(shè)定到期時(shí)間。對于定期更新或經(jīng)常更新的資源,這是可能的,但對于很少和不經(jīng)常更新的資源而言存在問題。他們是從緩存資源中受益最多的資源,但這使得它們很難更新。這是包含并鏈接到每個(gè)網(wǎng)頁的技術(shù)資源的典型代表:JavaScript和CSS文件很少更改,但當(dāng)它們更改時(shí),您希望它們能夠快速更新。
Web開發(fā)人員發(fā)明了一種Steve Sounders稱之為改變的技術(shù)。不經(jīng)常更新的文件以特定的方式命名:在他們的URL中,通常在文件名中添加修訂版(或版本)號。這樣,每一個(gè)這個(gè)資源的新版本都被認(rèn)為是永遠(yuǎn)不會(huì)有的資源變化并且可能在將來有很長的到期時(shí)間,通常是一年甚至更長。為了獲得新的版本,所有到它們的鏈接都必須改變,這就是這種方法的缺點(diǎn):通常由Web開發(fā)人員使用的工具鏈來處理額外的復(fù)雜性。當(dāng)不經(jīng)常變化的資源發(fā)生變化時(shí),它們會(huì)對經(jīng)常變化的資源產(chǎn)生額外的變化。當(dāng)這些被讀取時(shí),其他的新版本也被讀取。
這種技術(shù)還有一個(gè)額外的好處:同時(shí)更新兩個(gè)緩存資源不會(huì)導(dǎo)致一種資源的過時(shí)版本與另一種資源的新版本結(jié)合使用的情況。當(dāng)網(wǎng)站具有相互依賴的CSS樣式表或JS腳本時(shí),這是非常重要的,即它們相互依賴,因?yàn)樗鼈円孟嗤腍TML元素。
添加到revved資源中的修訂版本不需要像1.1.3這樣修訂字符串,或者甚至是單調(diào)增長的一組數(shù)字。它可以是防止碰撞的任何東西,比如散列或日期。
當(dāng)用戶按下重新加載按鈕時(shí),觸發(fā)重新驗(yàn)證。如果緩存的響應(yīng)包含“ Cache-control: must-revalidate
”標(biāo)題,它也會(huì)在正常瀏覽下觸發(fā)。另一個(gè)因素是首Advanced->Cache
選項(xiàng)面板中的緩存驗(yàn)證首選項(xiàng)。每次加載文檔時(shí)都有一個(gè)強(qiáng)制驗(yàn)證的選項(xiàng)。
當(dāng)達(dá)到緩存文檔的到期時(shí)間時(shí),它將被驗(yàn)證或再次提取。驗(yàn)證只有在服務(wù)器提供強(qiáng)驗(yàn)證器或弱驗(yàn)證器時(shí)才會(huì)發(fā)生。
ETag
響應(yīng)報(bào)頭是不透明到所述-用戶代理 ,可以作為強(qiáng)驗(yàn)證值使用。這意味著HTTP用戶代理(如瀏覽器)不知道該字符串代表什么,也無法預(yù)測其價(jià)值。如果ETag
頭部是資源響應(yīng)的一部分,則客戶端可以在未來請求的頭部中發(fā)出 If-None-Match
以驗(yàn)證緩存的資源。
Last-Modified
響應(yīng)報(bào)頭可以被用作弱驗(yàn)證器。它被認(rèn)為是微弱的,因?yàn)樗挥?秒的分辨率。如果Last-Modified
標(biāo)題出現(xiàn)在響應(yīng)中,則客戶端可以發(fā)出If-Modified-Since
請求標(biāo)頭來驗(yàn)證緩存的文檔。
當(dāng)發(fā)出驗(yàn)證請求時(shí),服務(wù)器可以忽略驗(yàn)證請求并以普通方式進(jìn)行響應(yīng)200
OK
,也可以返回304
Not Modified
(使用空的主體)來指示瀏覽器使用其緩存副本。后一個(gè)響應(yīng)還可以包括更新緩存文檔到期時(shí)間的標(biāo)題。
該Vary
HTTP響應(yīng)頭決定如何滿足未來的請求頭,以決定一個(gè)緩存的響應(yīng)是否可以使用,而不是從源服務(wù)器請求新的一個(gè)。
當(dāng)緩存接收到具有Vary
頭字段的緩存響應(yīng)可以滿足的請求時(shí),它不得使用該緩存的響應(yīng),除非頭中指定的所有頭字段Vary
在原始(緩存)請求和新請求中都匹配。
例如,這對于動(dòng)態(tài)提供內(nèi)容非常有用。使用Vary: User-Agent
標(biāo)題時(shí),緩存服務(wù)器在決定是否從緩存中提供頁面時(shí)應(yīng)考慮用戶代理。如果您向移動(dòng)用戶提供不同的內(nèi)容,它可以幫助您避免緩存可能會(huì)錯(cuò)誤地將您的網(wǎng)站的桌面版本提供給移動(dòng)用戶。此外,它可以幫助Google和其他搜索引擎發(fā)現(xiàn)頁面的移動(dòng)版本,并且可能會(huì)告訴他們沒有打算使用Cloaking。
Vary: User-Agent
由于User-Agent
移動(dòng)和桌面客戶端的標(biāo)頭值不同(“變化”),緩存將不會(huì)用于將移動(dòng)內(nèi)容錯(cuò)誤地提供給桌面用戶,反之亦然。
RFC 7234:超文本傳輸協(xié)議(HTTP / 1.1):緩存
緩存教程 - 馬克諾丁漢
HTTP緩存 - Ilya Grigorik
RedBot,一種檢查與緩存相關(guān)的HTTP標(biāo)頭的工具。