瀏覽器緩存實(shí)際上就是對(duì)一些靜態(tài)資源或是變化不多的資源進(jìn)行本地緩存以加快訪問(wèn)速度的一種方式,善于利用緩存機(jī)制可以給網(wǎng)站性能帶來(lái)非常大的提升,所以了解緩存機(jī)制原理是前端攻城師必須要掌握的。頁(yè)面請(qǐng)求一個(gè)資源主要有3種情況:
1. 本地?zé)o緩存或強(qiáng)制刷新:客戶端向服務(wù)器請(qǐng)求資源
2. 本地有緩存且未過(guò)期:客戶端使用本地資源
3. 本地有緩存已過(guò)期:客戶端重新請(qǐng)求服務(wù)器
首先介紹幾個(gè)術(shù)語(yǔ)
HTTP 1.0:
Pragma:Pragma頭域用來(lái)包含實(shí)現(xiàn)特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1協(xié)議中,它的含義和Cache-Control:no-cache相同
Expires: 用來(lái)標(biāo)識(shí)緩存失效時(shí)間,通常是一個(gè)時(shí)間值,如果是-1表示禁止緩存,如果存在Cache-Control的max-age,則此項(xiàng)被max-age覆蓋
HTTP 1.1:
Cache-Control:主要值有public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age
(1)打開(kāi)新窗口(_blank)
private、no-cache、must-revalidate 再次訪問(wèn)服務(wù)器
max-age?則在過(guò)期之前不會(huì)重復(fù)訪問(wèn)
(2)在地址欄回車
值為private或must-revalidate則只有第一次訪問(wèn)時(shí)會(huì)訪問(wèn)服務(wù)器,以后就不再訪問(wèn)。
值為no-cache,那么每次都會(huì)訪問(wèn)。
值為max-age,則在過(guò)期之前不會(huì)重復(fù)訪問(wèn)。
(3)按后退按扭
值為private、must-revalidate、max-age,則不會(huì)重訪問(wèn),
值為no-cache,則每次都重復(fù)訪問(wèn)
(4)按刷新按扭
無(wú)論為何值,都會(huì)重復(fù)訪問(wèn)
public所有內(nèi)容都將被緩存
private內(nèi)容只緩存到私有緩存中
no-cache所有內(nèi)容都不會(huì)被緩存
no-store所有內(nèi)容都不會(huì)被緩存到緩存或 Internet 臨時(shí)文件中
must-revalidation/proxy-revalidation如果緩存的內(nèi)容失效,請(qǐng)求必須發(fā)送到服務(wù)器/代理以進(jìn)行重新驗(yàn)證
max-age=xxx (xxx is numeric)緩存的內(nèi)容將在 xxx 秒后失效, 這個(gè)選項(xiàng)只在HTTP 1.1可用, 并如果和Last-Modified一起使用時(shí), 優(yōu)先級(jí)較高
ETag/If-None-Match:'XXX':服務(wù)器資源的標(biāo)識(shí)字符串,可以是md5也可以是時(shí)間戳,內(nèi)容發(fā)生變化時(shí),Etag也應(yīng)該發(fā)生變化,以及瀏覽器請(qǐng)求時(shí)需要比較Etag的頭信息
Last-Modified/If-Modified-Since: 服務(wù)器返回的文件最后修改時(shí)間,以及瀏覽器需要對(duì)比時(shí)提交的標(biāo)識(shí)字符串
主要過(guò)程是:瀏覽器A請(qǐng)求服務(wù)器資源B
1. A發(fā)現(xiàn)本地沒(méi)有緩存請(qǐng)求服務(wù)器下載資源B
2. 服務(wù)器返回資源B,并在頭部提供了Cache-Control:max-age=60,?Last-Modified:xxxx-xxx-xx,ETag:'abcdef';
3. 1分鐘內(nèi)A再次訪問(wèn)B,發(fā)現(xiàn)本地緩存未過(guò)期,直接使用本地資源,無(wú)需請(qǐng)求服務(wù)器
4. 1分鐘后A再次訪問(wèn)B,發(fā)現(xiàn)緩存過(guò)期,向服務(wù)器發(fā)出請(qǐng)求,并帶上If-Modified-Since:xxxx-xxx-xx和If-None-Match:'abcdef';
5. 服務(wù)器發(fā)現(xiàn)請(qǐng)求有If-Modified-Since和If-None-Match,對(duì)文件修改時(shí)間和Etag進(jìn)行了對(duì)比
6. 如果文件有變化則返回200,并返回文件內(nèi)容,并更新max-age,?Last-Modified和ETag
7. 如果文件未更新,則返回304,告訴瀏覽器繼續(xù)使用緩存文件,并更新max-age


問(wèn)題1 Pragma,Expires和Cache-Control的區(qū)別是啥
Pragma和Expires是http 1.0的標(biāo)準(zhǔn),支持http1.0和http1.1都可以使用,但是Expires存在服務(wù)器和客戶端時(shí)間不同步的問(wèn)題,所以一般采用:Cache-Control:max-age來(lái)代替Expires,但是只能在支持http1.1的瀏覽器使用
問(wèn)題2 Last-Modified和Etag區(qū)別是啥
Last-Modified看似可以解決文件修改問(wèn)題,但是存在文件內(nèi)容沒(méi)有被修改,修改時(shí)間卻發(fā)生變化的可能,為了解決這個(gè)問(wèn)你,Etag的出現(xiàn)能根據(jù)文件內(nèi)容來(lái)準(zhǔn)確保證緩存的正確性。