web緩存

爲何要用緩存

通常針對靜態資源如CSS,JS,圖片等使用緩存,緣由以下:css

  • 請求更快:經過將內容緩存在本地瀏覽器或距離最近的緩存服務器(如CDN),在不影響網站交互的前提下能夠大大加快網站加載速度。html

  • 節省帶寬:對於已緩存的文件,能夠減小請求帶寬甚至無需請求網絡。前端

  • 下降服務器壓力:在大量用戶併發請求的狀況下,服務器的性能受到限制,此時將一些靜態資源放置在網絡的多個節點,能夠起到均衡負載的做用,下降服務器的壓力。web

緩存分類

緩存分爲服務端側(server side,好比 Nginx、Apache)和客戶端側(client side,好比 web browser)。經常使用的服務端緩存有CDN緩存,客戶端緩存就是指瀏覽器緩存。數據庫

瀏覽器緩存機制詳解

緩存類型

瀏覽器緩存分爲強緩存協商緩存
1 強緩存: 瀏覽器在加載資源時,先根據這個資源的一些http header判斷它是否命中強緩存,強緩存若是命中,瀏覽器直接從本身的緩存中讀取資源,不會發請求到服務器。好比某個css文件,若是瀏覽器在加載它所 在的網頁時,這個css文件的緩存配置命中了強緩存,瀏覽器就直接從緩存中加載這個css,連請求都不會發送到網頁所在服務器;
2 協商緩存: 當強緩存沒有命中的時候,瀏覽器必定會發送一個請求到服務器,經過服務器端依據資源的另一些http header驗證這個資源是否命中協商緩存,若是協商緩存命中,服務器會將這個請求返回(304),可是不會返回這個資源的數據,而是告訴客戶端能夠直接 從緩存中加載這個資源,因而瀏覽器就又會從本身的緩存中去加載這個資源;若未命中請求,則將資源返回客戶端,並更新本地緩存數據(200)。瀏覽器

強緩存與協商緩存區別:強緩存不發請求到服務器,協商緩存會發請求到服務器。緩存

如何設置緩存

1 HTML Meta標籤控制緩存(非HTTP協議定義)
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
上述代碼的做用是告訴瀏覽器當前頁面不被緩存,每次訪問都須要去服務器拉取。這種方法使用上很簡單,但只有部分瀏覽器能夠支持,並且全部緩存代理服務器都不支持,由於代理不解析HTML內容自己。
2 HTTP頭信息控制緩存
HTTP頭信息控制緩存是經過Expires(強緩存)、Cache-control(強緩存)、Last-Modified/If-Modified-Since(協商緩存)、Etag/If-None-Match(協商緩存)實現,下面詳細介紹。安全

1)Expires是http1.0提出的一個表示資源過時時間的header,它描述的是一個絕對時間,由服務器返回,用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2016 23:55:55 GMT,服務器

讀取緩存數據條件:緩存過時時間(服務器的)< 當前時間(客戶端的

缺點:Expires是較老的強緩存管理header,因爲它是服務器返回的一個絕對時間,這樣存在一個問題, 若是客戶端的時間與服務器的時間相差很大(好比時鐘不一樣步,或者跨時區),那麼偏差就很大,因此在HTTP 1.1版開始,使用Cache-Control: max-age=秒替代。
2)Cache-Control描述的是一個相對時間,在進行緩存命中的時候,都是利用客戶端時間進行判斷,因此相比較Expires,Cache-Control的緩存管理更有效,安全一些。網絡

讀取緩存數據條件:上次緩存時間(客戶端的)+max-age < 當前時間(客戶端的)

Cache-Control值能夠是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age

各個消息中的指令含義以下:
Public指示響應可被任何緩存區緩存。
Private指示對於單個用戶的整個或部分響應消息,不能被共享緩存處理。這容許服務器僅僅描述當前用戶的部分響應消息,此響應消息對於其餘用戶的請求無效。
no-cache指示請求或響應消息不能緩存,該選項並非說能夠設置」不緩存「,而是須要和服務器確認
no-store在請求消息中發送將使得請求和響應消息都不使用緩存,徹底不存下來。
max-age指示客戶機能夠接收生存期不大於指定時間(以秒爲單位)的響應。上次緩存時間(客戶端的)+max-age(64200s)<客戶端當前時間
min-fresh指示客戶機能夠接收響應時間小於當前時間加上指定時間的響應。
max-stale指示客戶機能夠接收超出超時期間的響應消息。若是指定max-stale消息的值,那麼客戶機能夠接收超出超時期指定值以內的響應消息。

注意:這兩個header能夠只啓用一個,也能夠同時啓用,當response header中,Expires和Cache-Control同時存在時,Cache-Control優先級高於Expires:

3)Last-Modified/If-Modified-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用。

Last-Modified:標示這個響應資源的最後修改時間。web服務器在響應請求時,告訴瀏覽器資源的最後修改時間。
If-Modified-Since: 當資源過時時(強緩存失效),發現資源具備Last-Modified聲明,則再次向web服務器請求時帶上頭 If-Modified-Since,表示請求時間。web服務器收到請求後發現有頭If-Modified-Since 則與被請求資源的最後修改時間進行比對。若最後修改時間較新,說明資源又被改動過,則響應整片資源內容(寫在響應消息包體內),HTTP 200;若最後修改時間較舊,說明資源無新修改,則響應HTTP 304 (無需包體,節省瀏覽),告知瀏覽器繼續使用所保存的cache。
缺點

  • Last-Modified標註的最後修改只能精確到秒級,若是某些文件在1秒鐘之內,被修改屢次的話,它將不能準確標註文件的修改時間(沒法及時更新文件)

  • 若是某些文件會被按期生成,當有時內容並無任何變化,但Last-Modified卻改變了,致使文件無法使用緩存,有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形(沒法使用緩存)。

HTTP1.1中Etag解決了上述問題。

4)Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。
Etag:web服務器響應請求時,告訴瀏覽器當前資源在服務器的惟一標識(生成規則由服務器決定)。Apache中,ETag的值,默認是對文件的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後獲得的。
If-None-Match: 當資源過時時(使用Cache-Control標識的max-age),發現資源具備Etage聲明,則再次向web服務器請求時帶上頭If-None- Match (Etag的值)。web服務器收到請求後發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定返回200或304。
Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的惟一標識符,可以更加準確的控制緩存。Last-Modified與ETag一塊兒使用時,服務器會優先驗證ETag。
Etag

2 瀏覽器請求流程圖
瀏覽器第一次請求流程圖
瀏覽器再次請求時

三、用戶行爲與緩存

瀏覽器緩存行爲還有用戶的行爲有關,引用文章瀏覽器 HTTP 協議緩存機制詳解的結論

CDN緩存

CDN緩存屬於Cache服務器的一種。
CDN的全稱是Content Delivery Network,即內容分發網絡。其目的是經過在現有的Internet中增長一層新的網絡架構,將網站的內容發佈到最接近用戶的網絡"邊緣",使用戶可 以就近取得所需的內容,解決Internet網絡擁塞情況,提升用戶訪問網站的響應速度。從技術上全面解決因爲網絡帶寬小、用戶訪問量大、網點分佈不均等 緣由,解決用戶訪問網站的響應速度慢的根本緣由。
  經過上圖,咱們能夠了解到,使用了CDN緩存後的網站的訪問過程爲:
  1)、用戶向瀏覽器提供要訪問的域名;
   2)、瀏覽器調用域名解析庫對域名進行解析,因爲CDN對域名解析過程進行了調整,因此解析函數庫通常獲得的是該域名對應的CNAME記錄,爲了獲得實 際IP地址,瀏覽器須要再次對得到的CNAME域名進行解析以獲得實際的IP地址;在此過程當中,使用的全局負載均衡DNS解析,如根據地理位置信 息解析對應的IP地址,使得用戶能就近訪問。
  3)、這次解析獲得CDN緩存服務器的IP地址,瀏覽器在獲得實際的IP地址之後,向緩存服務器發出訪問請求;
  4)、若請求文件並未修改,返回304(充當服務器的角色)。若當前文件已過時,則緩存服務器根據瀏覽器提供的要訪問的域名,經過Cache內部專用DNS解析獲得此域名的實際IP地址,再由緩存服務器向此實際IP地址提交訪問請求
  5)、緩存服務器從實際IP地址得獲得內容之後,一方面在本地進行保存,以備之後使用,二方面把獲取的數據返回給客戶端,完成數據服務過程;
  6)、客戶端獲得由緩存服務器返回的數據之後顯示出來並完成整個瀏覽的數據請求過程。

 

在前端開發中,性能一直都是被你們所重視的一點,然而判斷一個網站的性能最直觀的就是看網頁打開的速度。其中提升網頁反應速度的一個方式就是使用緩存。一個優秀的緩存策略能夠縮短網頁請求資源的距離,減小延遲,而且因爲緩存文件能夠重複利用,還能夠減小帶寬,下降網絡負荷。那麼下面咱們就來看看服務器端緩存的原理。

 

緩存分類

 

web緩存分爲不少種,好比數據庫緩存、代理服務器緩存、還有咱們熟悉的CDN緩存,以及瀏覽器緩存。對於太多文字的閱讀其實我是拒絕的,因而就畫了個圖來解釋下。

 

瀏覽器經過代理服務器向源服務器發起請求的原理以下圖,

 

 

瀏覽器先向代理服務器發起Web請求,再將請求轉發到源服務器。它屬於共享緩存,因此不少地方均可以使用其緩存資源,所以對於節省流量有很大做用。

 

瀏覽器緩存是將文件保存在客戶端,在同一個會話過程當中會檢查緩存的副本是否足夠新,在後退網頁時,訪問過的資源能夠從瀏覽器緩存中拿出使用。經過減小服務器處理請求的數量,用戶將得到更快的體驗

 

下面我就來着重講下傳說中的瀏覽器緩存。

 

瀏覽器緩存

 

頁面的緩存狀態是由header決定的,header的參數有四種:

 

1、Cache-Control:

 

一、max-age(單位爲s)指定設置緩存最大的有效時間,定義的是時間長短。當瀏覽器向服務器發送請求後,在max-age這段時間裏瀏覽器就不會再向服務器發送請求了。

 

咱們來找個資源看下。好比shang.qq.com上的css資源,max-age=2592000,也就是說緩存有效期爲2592000秒(也就是30天)。因而在30天內都會使用這個版本的資源,即便服務器上的資源發生了變化,瀏覽器也不會獲得通知。max-age會覆蓋掉Expires,後面會有討論。

 

 

二、s-maxage(單位爲s)同max-age,只用於共享緩存(好比CDN緩存)。

 

好比,當s-maxage=60時,在這60秒中,即便更新了CDN的內容,瀏覽器也不會進行請求。也就是說max-age用於普通緩存,而s-maxage用於代理緩存。若是存在s-maxage,則會覆蓋掉max-age和Expires header。

 

三、public 指定響應會被緩存,而且在多用戶間共享。也就是下圖的意思。若是沒有指定public仍是private,則默認爲public。

 

 

四、private 響應只做爲私有的緩存(見下圖),不能在用戶間共享。若是要求HTTP認證,響應會自動設置爲private。

 

 

五、no-cache 指定不緩存響應,代表資源不進行緩存,好比,

 

 

可是設置了no-cache以後並不表明瀏覽器不緩存,而是在緩存前要向服務器確認資源是否被更改。所以有的時候只設置no-cache防止緩存仍是不夠保險,還能夠加上private指令,將過時時間設爲過去的時間。

 

六、no-store 絕對禁止緩存,一看就知道若是用了這個命令固然就是不會進行緩存啦~每次請求資源都要從服務器從新獲取。

 

七、must-revalidate指定若是頁面是過時的,則去服務器進行獲取。這個指令並不經常使用,就不作過多的討論了。

 

2、Expires

 

緩存過時時間,用來指定資源到期的時間,是服務器端的具體的時間點。也就是說,Expires=max-age + 請求時間,須要和Last-modified結合使用。但在上面咱們提到過,cache-control的優先級更高。 Expires是Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過時時間前瀏覽器能夠直接從瀏覽器緩存取數據,而無需再次請求。

 

 

3、Last-modified 

 

服務器端文件的最後修改時間,須要和cache-control共同使用,是檢查服務器端資源是否更新的一種方式。當瀏覽器再次進行請求時,會向服務器傳送If-Modified-Since報頭,詢問Last-Modified時間點以後資源是否被修改過。若是沒有修改,則返回碼爲304,使用緩存;若是修改過,則再次去服務器請求資源,返回碼和首次請求相同爲200,資源爲服務器最新資源。

 

以下圖,最後修改時間爲2014年12月19日星期五2點50分47秒

 

 

4、ETag

        

根據實體內容生成一段hash字符串,標識資源的狀態,由服務端產生。瀏覽器會將這串字符串傳回服務器,驗證資源是否已經修改,若是沒有修改,過程以下:

 

 

使用ETag能夠解決Last-modified存在的一些問題:

 

a、某些服務器不能精確獲得資源的最後修改時間,這樣就沒法經過最後修改時間判斷資源是否更新

 

b、若是資源修改很是頻繁,在秒如下的時間內進行修改,而Last-modified只能精確到秒

 

c、一些資源的最後修改時間改變了,可是內容沒改變,使用ETag就認爲資源仍是沒有修改的。

 

使用緩存流程

 

仍是用圖說話,下面是我所總結的從瀏覽器請求到展現資源的過程:

 

 

cache-control指令使用

 

說了那麼多cache-control的指令,那麼如何選擇使用哪些指令呢?我仍是不說話==

 

 

額外的

 

除了開頭提到的那麼多緩存方式之外,還有一種咱們都熟悉的緩存方式,LocalStorage和sessionStorage(好像是兩種23333)。

 

LocalStorage是一種本地存儲的公共資源,域名下不少應用共享這份資源會有風險;LocalStorage是以頁面域名劃分的,若是有多個等價域名之間的LocalStorage不互通,則會形成緩存多份浪費。

 

LocalStorage在PC上的兼容性不太好,並且當網絡速度快、協商緩存響應快時使用localStorage的速度比不上304。而且不能緩存css文件。而移動端因爲網速慢,使用localStorage要快於304。

 

在html中加載一個png圖,首次加載的時候時間以下圖,

 

 

然而將圖片使用了LocalStorage存儲後,再次刷新後加載時間爲0。

 

 

而相對LocalStorage來講,SessionStorage的數據只存儲到特定的會話中,不屬於持久化的存儲,因此關閉瀏覽器會清除數據。和localstorage具備相同的方法。

 

在前端開發中緩存是必不可少的,那麼使用怎樣的緩存方式更高效、讓咱們項目的性能更優,仍是須要咱們仔細斟酌。

相關文章
相關標籤/搜索