摘要:當(dāng)然,緩存不止這一種,比如在中定義的某些也可以實(shí)現(xiàn)自定義緩存的但,實(shí)際情況是,這些只能在本地文件中使用,如果是服務(wù)器則默認(rèn)被覆蓋。
親,你知道緩存是什么嗎?
其實(shí)緩存就像辦健身卡,我第一次花了699辦了一年的卡之后,接下來(lái)的一年我都可以免費(fèi)鍛煉。 在web 中, 我們交的不是錢,而是空間,我們耗費(fèi)一定的空間之后,能夠獲得網(wǎng)頁(yè)打開(kāi)速度質(zhì)的飛躍。 當(dāng)我們第一次訪問(wèn)一個(gè)頁(yè)面時(shí),我們需要交納一定的空間, 將下載的css,js,html已經(jīng)img等相關(guān)資源保存在本地。 在第二次,第三次。。。訪問(wèn)時(shí),就可以不用去下載文件了。
通常來(lái)說(shuō),設(shè)置文件的緩存有兩種方式,一種是在服務(wù)器內(nèi)設(shè)置響應(yīng)頭文件,另外一個(gè)是使用h5的manifest文件來(lái)進(jìn)行相關(guān)設(shè)置.
我們先看看報(bào)文設(shè)置響應(yīng)頭的方式吧
這種方式設(shè)置的緩存有兩種,一種是需要服務(wù)器驗(yàn)證,另外一種是不用發(fā)送請(qǐng)求驗(yàn)證。
ETag/Last-Modified這兩種方式做法類似,都要向服務(wù)器發(fā)送一次請(qǐng)求進(jìn)行驗(yàn)證。簡(jiǎn)直,緩存就緩存唄,為什么還要驗(yàn)證呢? 其實(shí),這是該協(xié)議的一種特有方式,發(fā)送一次驗(yàn)證主要是檢查文件是否發(fā)生變化。
ETagETag是用來(lái)計(jì)算文件的內(nèi)容是否發(fā)生變化,比如,你在文件中刪除一個(gè)空格,這樣都算文件內(nèi)容發(fā)生變化。 通常做法是用md5或者SHA1算法,計(jì)算出文件的唯一值。 在前端其實(shí)都可以完成, 找到一個(gè)文件文件解析的md5算法,然后將文件傳入,就可以得到ETag的值。 不過(guò)這里,我們著重點(diǎn)并不是讓你生成Etag,而是看看ETag在緩存中的重要作用。
ETag是HTTP/1.1A的一種辦法,由Web服務(wù)器生成,并寫入響應(yīng)頭中。
//response Headers ETag:"751F63A30AB5F98F855D1D90D217B356"
接著,到了瀏覽器之后,便緩存在本地。 當(dāng)下次打開(kāi)同樣的文章時(shí),會(huì)在請(qǐng)求頭中發(fā)送If-None-Match, 給服務(wù)器檢查文件是否發(fā)生變化。如果沒(méi)有,則告訴瀏覽器使用本地的,否則返回新文件
//request Headers If-None-Match: "751F63A30AB5F98F855D1D90D217B356"
通常情況下,服務(wù)器默認(rèn)是打開(kāi)Etag的,但是為了防止你的同事,或者后臺(tái)哥哥的后臺(tái)配置文件不正確,關(guān)閉了Etag,這時(shí)候,就需要你對(duì)對(duì)配置文件做一些設(shè)置。 這里我以Nginx為例:
打開(kāi)ngnix.conf文件,檢查是否有以下語(yǔ)句:
etag off; more_set_headers -s 404 -t "ETag"; more_clear_headers "Etag";
如果有則將其刪除掉。然后重啟nginx就可以了。他們將Etag關(guān)閉的原因其實(shí)也很簡(jiǎn)單,就是因?yàn)?,Etag打開(kāi)之后會(huì)增加服務(wù)器的負(fù)載,造成性能的局限性,所以,關(guān)閉或者打開(kāi)Etag都要經(jīng)過(guò)權(quán)衡的。
Last-Modified這和文檔內(nèi)容信息驗(yàn)證不同,這里采用的是日期驗(yàn)證辦法。 即,服務(wù)器上會(huì)對(duì)文件打上一個(gè)文件改動(dòng)的日期,然后客戶端接受該日期,下次請(qǐng)求時(shí),返回該日期,服務(wù)器驗(yàn)證,如果日期未變,則告訴瀏覽器使用本地緩存即可。
即,在服務(wù)器的相應(yīng)頭中,可以設(shè)置Last-Modified,來(lái)啟用這一緩存協(xié)議.
//Response Header Last-Modified:Tue, 03 Mar 2015 01:38:18 GMT
接受到這一響應(yīng)頭之后,瀏覽器會(huì)對(duì)該文件做一個(gè)緩存,并保存該日期。當(dāng)下次請(qǐng)求的時(shí)候,會(huì)通過(guò)If-Modified-Since將日期傳入并驗(yàn)證:
If-Modified-Since:Tue, 03 Mar 2015 01:38:18 GMT
如果日期未變,則告訴瀏覽器使用緩存。
那我們通常應(yīng)該怎樣啟用服務(wù)器這一功能呢?
默認(rèn)情況下,服務(wù)器會(huì)對(duì)靜態(tài)資源發(fā)送Last-modified的tag。 但是,需要注意,Last-Modified的更新時(shí)間只能以秒來(lái)計(jì),如果你文件改動(dòng)過(guò)于頻繁,Last-Modified是無(wú)效的(不過(guò),誰(shuí)牛逼到1s內(nèi)能多次更新文件嘞~)
實(shí)際上.Last-Modified的這個(gè)標(biāo)簽的我們通常并不會(huì)多帶帶使用它,通常與expires結(jié)合,形成一個(gè)可降級(jí)的緩存.
Expires/Cache協(xié)議與上述驗(yàn)證協(xié)議最大的不同在于,他可以省略發(fā)送驗(yàn)證請(qǐng)求環(huán)節(jié),不需要服務(wù)器的驗(yàn)證,而直接使用本地緩存。 通常這種方式,適用于,項(xiàng)目穩(wěn)定,版本迭代不多的時(shí)候。
Expires在服務(wù)器端可以設(shè)置Expires的一個(gè)絕對(duì)時(shí)間。
//Response Headers Expires:Tue, 03 May 2016 09:33:34 GMT
這告訴瀏覽器,在2016.5.3號(hào)之前,可以直接使用該文本的緩存副本。但是,可能會(huì)因?yàn)榉?wù)器和客戶端的GMT時(shí)間不同,會(huì)有一定的bug。 所以,這里只提議在長(zhǎng)時(shí)間緩存的情況下使用。否則,應(yīng)該選擇Cache-Control.
那在服務(wù)器端該怎么設(shè)置呢? 這里以nginx為例:
location ~* .(?:css|js)$ { expires 1d; access_log off; add_header Cache-Control "public"; }
通過(guò)expires設(shè)置過(guò)期時(shí)間為一天,此時(shí),服務(wù)器會(huì)根據(jù)當(dāng)前的時(shí)間,加上一天.同時(shí)添加Expires和Cache-Control頭部標(biāo)簽。
即,得到的Response Header為:
Expires: Fri, 28 Feb 2014 10:42:09 GMT Cache-Control: max-age=86400 //24*60*60
(HTTP規(guī)定,如果出現(xiàn)max-age和expires,則max-age默認(rèn)覆蓋掉expires)
當(dāng)expires為負(fù)數(shù)表示no-cache,正數(shù)或零表示max-age=time。
如果你不想緩存,可以直接設(shè)置:
expires -1; //永遠(yuǎn)過(guò)期,Cache-Control: no-cache
詳細(xì)可以直接參閱:nginx配置
Cache-Control這應(yīng)該是HTTP1.1為了解決HTTP1.0中expires的時(shí)間差的bug,而新添加的一個(gè)tag. 他的配置項(xiàng)很多,其實(shí)完全都可以取代expires(現(xiàn)在大多數(shù)服務(wù)器都支持). 引用一段原話:
Cache-Control 頭在 HTTP/1.1 規(guī)范中定義,取代了之前用來(lái)定義響應(yīng)緩存策略的頭(例如 Expires)。當(dāng)前的所有瀏覽器都支持 Cache-Control,因此,使用它就夠了。
不過(guò),目前大部分服務(wù)器都會(huì)將兩者添加上,因?yàn)镠TTP規(guī)定,如果Cache-Control和expires同時(shí)出現(xiàn)的話,expires會(huì)默認(rèn)被覆蓋掉。
此時(shí),返回的響應(yīng)碼不再是304(文件未改動(dòng)),而是200(資源成功訪問(wèn)).
當(dāng)前每次發(fā)送請(qǐng)求之前瀏覽器會(huì)檢查緩存系統(tǒng)里,是否有相應(yīng)文件的備份,如果有的話,則直接從本地模仿一個(gè)Response頭
理論知識(shí)鋪墊完畢,我們來(lái)take a look. 看看cache-control 有哪些可以配置的屬性(以下屬性都跟在cache-control后)
public: 共有緩存,可被緩存代理服務(wù)器緩存,比如CDN private: 私有緩存,不能被共有緩存代理服務(wù)器緩存,可被用戶的代理緩存如瀏覽器。 max-age=[秒]:表示在這個(gè)時(shí)間范圍內(nèi)緩存是新鮮的無(wú)需更新。類似Expires時(shí)間,不過(guò)這個(gè)時(shí)間是相對(duì)的,而不是絕對(duì)的。也就是某次請(qǐng)求成功后多少秒內(nèi)緩存是新鮮的。 s-maxage=[秒]:類似max-age, 除了僅應(yīng)用于共享緩存(如代理)。 no-cache:這里不是不緩存的意思,只是每次在使用緩存之前都強(qiáng)制發(fā)送請(qǐng)求給源服務(wù)器進(jìn)行驗(yàn)證,檢查文件該沒(méi)改變(其實(shí)這里和ETag/Last區(qū)別不大) no-store:就是禁止緩存,不讓瀏覽器保留緩存副本 must-revalidate:告訴瀏覽器,你這必須再次驗(yàn)證檢查信息是否過(guò)期, 返回的代號(hào)就不是200而是304了。 proxy-revalidate:類似must-revalidate,除了只能應(yīng)用于代理緩存。
比如,這里我可以設(shè)置Cache-Control為:
//Response Headers Cache-Control:private, max-age=0, must-revalidate
該文件是一個(gè)私有文件,只能被瀏覽器緩存,而不能被代理緩存。max-age標(biāo)識(shí)該緩存立即過(guò)期,其實(shí)和no-cache實(shí)際上區(qū)別不大. 然后must-revalidate告訴瀏覽器,你必須給我再驗(yàn)證文件過(guò)沒(méi)過(guò)期,比如接下來(lái)可能會(huì)驗(yàn)證Last-Modified或者ETag.如果沒(méi)有過(guò)期則使用本地緩存.
其實(shí)上面可以直接等同于:
//Response Headers Cache-Control:private,no-cache
使用no-store的結(jié)果
//Response Headers Cache-Control:no-store;
這樣表明,不管一不一樣都需要重新下載. 強(qiáng)烈表示,不讓你使用緩存文件。后續(xù)的就不會(huì)去驗(yàn)證ETag了。
當(dāng)然,如果你將IE6那種古老的瀏覽器考慮進(jìn)來(lái)的話,那你干脆就做的不要臉一點(diǎn),直接用下面的tag就行:
Cache-Control: no-cache, no-store, must-revalidate //HTTP1.1 Pragma: no-cache //HTTP1.0 Expires: 0 //Proxy
不過(guò)現(xiàn)在基本上也沒(méi)有不支持Cache-Control的瀏覽器了。所以,正常情況下,可以直接使用.如下的策略來(lái)進(jìn)行設(shè)置:(From google developer)
我們通常在nginx怎么配置對(duì)應(yīng)的cache-control頭呢?
##設(shè)置no-cache //Nginx expires -1; //cache-control Cache-Control:no-cache ##設(shè)置max-age=0 //Nginx expires 0; //cache-control Cache-Control:max-age=0 ##設(shè)置其他頭部 //nginx add_header Cache-Control "no-cache"; add_header Pragma no-cache;
上面說(shuō)的基本上是服務(wù)器的響應(yīng)頭,那在瀏覽器的Request headers里存在cache-control代表什么呢?
當(dāng)請(qǐng)求頭中有:Cache-Control: max-age=0,表示緩存需要進(jìn)行驗(yàn)證(ETag||Last-Modified),如果緩存未過(guò)期,則可以使用。
當(dāng)請(qǐng)求頭中有:Cache-Control: no-cache,表示瀏覽器只能獲取最新的文件。 和Response Header中的no-store相對(duì)應(yīng)。
上面介紹的last/ETag/Expires/Cache都是HTTP協(xié)議的緩存策略。當(dāng)然,緩存不止這一種,比如在HTML 4.0中定義的某些meta也可以實(shí)現(xiàn)自定義緩存的
但,實(shí)際情況是,這些meta只能在file:// 本地文件中使用,如果是服務(wù)器則默認(rèn)被覆蓋?,F(xiàn)在目前主流的就是使用HTTP1.1協(xié)議緩存
不過(guò)我們一般都不會(huì)多帶帶使用某一項(xiàng)。 但是,組合之后他們的效果是怎樣的呢?
如果你的網(wǎng)頁(yè)不是什么特別定制化的(私密)的,使用緩存能給你網(wǎng)站的性能帶來(lái)極大的提升。所以很推薦使用。
一個(gè)網(wǎng)站,說(shuō)白了就是HTML+JS+CSS+fonts+img 這幾類文件(視頻就呵呵了).
我們可以針對(duì)這幾類文件做一些緩存層級(jí)
文件 | 緩存層級(jí) |
---|---|
HTML | Cache-Control: no-cache,must-revalidate |
JS | Cache-Control:private,max-age=86400 |
CSS | Cache-Control:max-age=2629000 |
imgfonts | Cache-Control:max-age=2629000 |
上面只是一個(gè)簡(jiǎn)單的設(shè)置,要知道HTML是一定不能緩存的(大部分網(wǎng)頁(yè))。 緩存設(shè)置時(shí)間應(yīng)該在你版本穩(wěn)定之后設(shè)置,否則會(huì)得不償失。 另外設(shè)置Cache-Control還可以配合ETag或者Last-Modified進(jìn)行補(bǔ)償驗(yàn)證,如果后面文件變化也可以及時(shí)反映出來(lái)。
清除緩存最常用的辦法就是修改文件的版本號(hào),或者生成隨機(jī)文件名。
如果你只是在本地測(cè)試,想手動(dòng)清楚緩存的話,可以使用.
但是在Mac中不一樣,使用command+R = F5刷新, command+shift+R= ctrl+F5硬性重新加載.
另外,即使你設(shè)置了緩存策略,但是他也不會(huì)進(jìn)行緩存的文件。 這些文件包括動(dòng)態(tài)認(rèn)證的文件,比如需要cookie驗(yàn)證,輸入驗(yàn)證碼等產(chǎn)生的文件。POST請(qǐng)求文件不能被緩存。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/61785.html
摘要:總結(jié)強(qiáng)制緩存只有首次請(qǐng)求才會(huì)跟服務(wù)器通信,讀取緩存資源時(shí)不會(huì)發(fā)出任何請(qǐng)求,資源的狀態(tài)碼為,資源的為或者,版本的實(shí)現(xiàn)優(yōu)先級(jí)會(huì)高于版本的實(shí)現(xiàn)。 一 強(qiáng)制緩存 強(qiáng)制緩存整體流程比較簡(jiǎn)單,就是在第一次訪問(wèn)服務(wù)器取到數(shù)據(jù)之后,在過(guò)期時(shí)間之內(nèi)不會(huì)再去重復(fù)請(qǐng)求。實(shí)現(xiàn)這個(gè)流程的核心就是如何知道當(dāng)前時(shí)間是否超過(guò)了過(guò)期時(shí)間。 強(qiáng)制緩存的過(guò)期時(shí)間通過(guò)第一次訪問(wèn)服務(wù)器時(shí)返回的響應(yīng)頭獲取。在 http 1.0 ...
摘要:瀏覽器緩存作為性能優(yōu)化的重要一環(huán),對(duì)于前端而言,重要性不言而喻。根據(jù)瀏覽器發(fā)送的修改時(shí)間和服務(wù)端的修改時(shí)間進(jìn)行比對(duì),一致的話代表資源沒(méi)有改變,服務(wù)端返回正文為空的響應(yīng),讓瀏覽器中緩存中讀取資源,這就大大減小了請(qǐng)求的消耗。 瀏覽器緩存作為性能優(yōu)化的重要一環(huán),對(duì)于前端而言,重要性不言而喻。以前總是一知半解的,所以這次好好整理總結(jié)了一下。 1、緩存機(jī)制 首先我們來(lái)總體感知一下它的匹配流程,如...
摘要:緩存緩存,也叫網(wǎng)關(guān)緩存反向代理緩存。瀏覽器先向網(wǎng)關(guān)發(fā)起請(qǐng)求,網(wǎng)關(guān)服務(wù)器后面對(duì)應(yīng)著一臺(tái)或多臺(tái)負(fù)載均衡源服務(wù)器,會(huì)根據(jù)它們的負(fù)載請(qǐng)求,動(dòng)態(tài)將請(qǐng)求轉(zhuǎn)發(fā)到合適的源服務(wù)器上。雖然這種架構(gòu)負(fù)載均衡源服務(wù)器之間的緩存沒(méi)法共享,但卻擁有更好的處擴(kuò)展性。 一、前言? 工作上遇到一個(gè)這樣的需求,一個(gè)H5頁(yè)面在APP端,如果勾選已讀狀態(tài),則下次打開(kāi)該鏈接,會(huì)跳過(guò)此頁(yè)面。用到了HTML5 的本地存儲(chǔ) API ...
摘要:最近在項(xiàng)目中遇到了瀏覽器因緩存問(wèn)題未能成功向后端發(fā)送類型請(qǐng)求的,然后順藤摸瓜順便看了看緩存的知識(shí),覺(jué)得有必要總結(jié)一下。是服務(wù)器響應(yīng)消息頭字段,在響應(yīng)請(qǐng)求時(shí)告訴瀏覽器在過(guò)期時(shí)間前瀏覽器可以直接從瀏覽器緩存取數(shù)據(jù),而無(wú)需再次請(qǐng)求。 最近在項(xiàng)目中遇到了IE瀏覽器因緩存問(wèn)題未能成功向后端發(fā)送GET類型請(qǐng)求的bug,然后順藤摸瓜順便看了看緩存的知識(shí),覺(jué)得有必要總結(jié)一下。 在前端開(kāi)發(fā)中,性能一直都...
摘要:最近在項(xiàng)目中遇到了瀏覽器因緩存問(wèn)題未能成功向后端發(fā)送類型請(qǐng)求的,然后順藤摸瓜順便看了看緩存的知識(shí),覺(jué)得有必要總結(jié)一下。是服務(wù)器響應(yīng)消息頭字段,在響應(yīng)請(qǐng)求時(shí)告訴瀏覽器在過(guò)期時(shí)間前瀏覽器可以直接從瀏覽器緩存取數(shù)據(jù),而無(wú)需再次請(qǐng)求。 最近在項(xiàng)目中遇到了IE瀏覽器因緩存問(wèn)題未能成功向后端發(fā)送GET類型請(qǐng)求的bug,然后順藤摸瓜順便看了看緩存的知識(shí),覺(jué)得有必要總結(jié)一下。 在前端開(kāi)發(fā)中,性能一直都...
摘要:請(qǐng)求過(guò)程如下瀏覽器請(qǐng)求靜態(tài)資源服務(wù)器讀取磁盤文件,返給瀏覽器,同時(shí)帶上文件的唯一標(biāo)識(shí)當(dāng)瀏覽器上的緩存文件過(guò)期時(shí),瀏覽器帶上請(qǐng)求頭等于上一次請(qǐng)求的請(qǐng)求服務(wù)器服務(wù)器比較請(qǐng)求頭里的和文件的。 前言 Http簡(jiǎn)介 瀏覽器和服務(wù)器之間通信是通過(guò)HTTP協(xié)議,HTTP協(xié)議永遠(yuǎn)都是客戶端發(fā)起請(qǐng)求,服務(wù)器回送響應(yīng)。模型如下: showImg(https://segmentfault.com/img/b...
閱讀 1130·2021-11-16 11:42
閱讀 2910·2021-10-12 10:18
閱讀 2868·2021-09-24 09:48
閱讀 3471·2019-08-30 15:56
閱讀 1536·2019-08-30 14:17
閱讀 3052·2019-08-29 12:14
閱讀 914·2019-08-27 10:51
閱讀 2032·2019-08-26 13:28