瀏覽器緩存,也就是客戶端緩存,既是網(wǎng)頁性能優(yōu)化里面靜態(tài)資源相關(guān)優(yōu)化的一大利器,也是無數(shù)web開發(fā)人員在工作過程不可避免的一大問題,所以在產(chǎn)品開發(fā)的時(shí)候我們總是想辦法避免緩存產(chǎn)生,而在產(chǎn)品發(fā)布之時(shí)又在想策略管理緩存提升網(wǎng)頁的訪問速度。了解瀏覽器的緩存命中原理,是開發(fā)web應(yīng)用的基礎(chǔ),本文著眼于此,學(xué)習(xí)瀏覽器緩存的相關(guān)知識(shí),總結(jié)緩存避免和緩存管理的方法,結(jié)合具體的場(chǎng)景說明緩存的相關(guān)問題。希望能對(duì)有需要的人有所幫助。
1. 瀏覽器緩存基本認(rèn)識(shí)
它分為強(qiáng)緩存和協(xié)商緩存:
1)瀏覽器在加載資源時(shí),先根據(jù)這個(gè)資源的一些http header判斷它是否命中強(qiáng)緩存,強(qiáng)緩存如果命中,瀏覽器直接從自己的緩存中讀取資源,不會(huì)發(fā)請(qǐng)求到服務(wù)器。比如某個(gè)css文件,如果瀏覽器在加載它所在的網(wǎng)頁時(shí),這個(gè)css文件的緩存配置命中了強(qiáng)緩存,瀏覽器就直接從緩存中加載這個(gè)css,連請(qǐng)求都不會(huì)發(fā)送到網(wǎng)頁所在服務(wù)器;
2)當(dāng)強(qiáng)緩存沒有命中的時(shí)候,瀏覽器一定會(huì)發(fā)送一個(gè)請(qǐng)求到服務(wù)器,通過服務(wù)器端依據(jù)資源的另外一些http header驗(yàn)證這個(gè)資源是否命中協(xié)商緩存,如果協(xié)商緩存命中,服務(wù)器會(huì)將這個(gè)請(qǐng)求返回,但是不會(huì)返回這個(gè)資源的數(shù)據(jù),而是告訴客戶端可以直接從緩存中加載這個(gè)資源,于是瀏覽器就又會(huì)從自己的緩存中去加載這個(gè)資源;
3)強(qiáng)緩存與協(xié)商緩存的共同點(diǎn)是:如果命中,都是從客戶端緩存中加載資源,而不是從服務(wù)器加載資源數(shù)據(jù);區(qū)別是:強(qiáng)緩存不發(fā)請(qǐng)求到服務(wù)器,協(xié)商緩存會(huì)發(fā)請(qǐng)求到服務(wù)器。
4)當(dāng)協(xié)商緩存也沒有命中的時(shí)候,瀏覽器直接從服務(wù)器加載資源數(shù)據(jù)。
2. 強(qiáng)緩存的原理
當(dāng)瀏覽器對(duì)某個(gè)資源的請(qǐng)求命中了強(qiáng)緩存時(shí),返回的http狀態(tài)為200,在chrome的開發(fā)者工具的network里面size會(huì)顯示為from cache,比如京東的首頁里就有很多靜態(tài)資源配置了強(qiáng)緩存,用chrome打開幾次,再用f12查看network,可以看到有不少請(qǐng)求就是從緩存中加載的:
強(qiáng)緩存是利用Expires或者Cache-Control這兩個(gè)http response header實(shí)現(xiàn)的,它們都用來表示資源在客戶端緩存的有效期。
Expires是http1.0提出的一個(gè)表示資源過期時(shí)間的header,它描述的是一個(gè)絕對(duì)時(shí)間,由服務(wù)器返回,用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2037 23:55:55 GMT,它的緩存原理是:
1)瀏覽器第一次跟服務(wù)器請(qǐng)求一個(gè)資源,服務(wù)器在返回這個(gè)資源的同時(shí),在respone的header加上Expires的header,如:
2)瀏覽器在接收到這個(gè)資源后,會(huì)把這個(gè)資源連同所有response header一起緩存下來(所以緩存命中的請(qǐng)求返回的header并不是來自服務(wù)器,而是來自之前緩存的header);
3)瀏覽器再請(qǐng)求這個(gè)資源時(shí),先從緩存中尋找,找到這個(gè)資源后,拿出它的Expires跟當(dāng)前的請(qǐng)求時(shí)間比較,如果請(qǐng)求時(shí)間在Expires指定的時(shí)間之前,就能命中緩存,否則就不行。
4)如果緩存沒有命中,瀏覽器直接從服務(wù)器加載資源時(shí),Expires Header在重新加載的時(shí)候會(huì)被更新。
Expires是較老的強(qiáng)緩存管理header,由于它是服務(wù)器返回的一個(gè)絕對(duì)時(shí)間,在服務(wù)器時(shí)間與客戶端時(shí)間相差較大時(shí),緩存管理容易出現(xiàn)問題,比如隨意修改下客戶端時(shí)間,就能影響緩存命中的結(jié)果。所以在http1.1的時(shí)候,提出了一個(gè)新的header,就是Cache-Control,這是一個(gè)相對(duì)時(shí)間,在配置緩存的時(shí)候,以秒為單位,用數(shù)值表示,如:Cache-Control:max-age=315360000,它的緩存原理是:
1)瀏覽器第一次跟服務(wù)器請(qǐng)求一個(gè)資源,服務(wù)器在返回這個(gè)資源的同時(shí),在respone的header加上Cache-Control的header,如:
2)瀏覽器在接收到這個(gè)資源后,會(huì)把這個(gè)資源連同所有response header一起緩存下來;
3)瀏覽器再請(qǐng)求這個(gè)資源時(shí),先從緩存中尋找,找到這個(gè)資源后,根據(jù)它第一次的請(qǐng)求時(shí)間和Cache-Control設(shè)定的有效期,計(jì)算出一個(gè)資源過期時(shí)間,再拿這個(gè)過期時(shí)間跟當(dāng)前的請(qǐng)求時(shí)間比較,如果請(qǐng)求時(shí)間在過期時(shí)間之前,就能命中緩存,否則就不行。
4)如果緩存沒有命中,瀏覽器直接從服務(wù)器加載資源時(shí),Cache-Control Header在重新加載的時(shí)候會(huì)被更新。
Cache-Control描述的是一個(gè)相對(duì)時(shí)間,在進(jìn)行緩存命中的時(shí)候,都是利用客戶端時(shí)間進(jìn)行判斷,所以相比較Expires,Cache-Control的緩存管理更有效,安全一些。
這兩個(gè)header可以只啟用一個(gè),也可以同時(shí)啟用,當(dāng)response header中,Expires和Cache-Control同時(shí)存在時(shí),Cache-Control優(yōu)先級(jí)高于Expires:
3. 強(qiáng)緩存的管理
前面介紹的是強(qiáng)緩存的原理,在實(shí)際應(yīng)用中我們會(huì)碰到需要強(qiáng)緩存的場(chǎng)景和不需要強(qiáng)緩存的場(chǎng)景,通常有2種方式來設(shè)置是否啟用強(qiáng)緩存:
1)通過代碼的方式,在web服務(wù)器返回的響應(yīng)中添加Expires和Cache-Control Header;
2)通過配置web服務(wù)器的方式,讓web服務(wù)器在響應(yīng)資源的時(shí)候統(tǒng)一添加Expires和Cache-Control Header。
比如在javaweb里面,我們可以使用類似下面的代碼設(shè)置強(qiáng)緩存:
java.util.Date date = new java.util.Date(); response.setDateHeader("Expires",date.getTime()+20000); //Expires:過時(shí)期限值 response.setHeader("Cache-Control", "public"); //Cache-Control來控制頁面的緩存與否,public:瀏覽器和緩存服務(wù)器都可以緩存頁面信息; response.setHeader("Pragma", "Pragma"); //Pragma:設(shè)置頁面是否緩存,為Pragma則緩存,no-cache則不緩存
掃碼二維碼 獲取免費(fèi)視頻學(xué)習(xí)資料
- 本文固定鏈接: http://www.wangchenghua.com/post/4608/
- 轉(zhuǎn)載請(qǐng)注明:轉(zhuǎn)載必須在正文中標(biāo)注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費(fèi)視頻資料