瀏覽器緩存機制探索

做者:小麻姐@毛豆前端javascript

瀏覽器緩存

首先用一張圖瞭解下緩存:html

結果

爲何要緩存

咱們從性能方面分析下爲何要緩存前端

緩存的做用

緩存可以對已有的資源進行重用,減小延遲和網絡阻塞,達到減小某個資源展現的時間。 其實咱們對於頁面靜態資源的要求就兩點java

一、靜態資源加載速度git

二、頁面渲染速度github

頁面渲染速度創建在資源加載速度之上,但不一樣資源類型的加載順序和時機也會對其產生影響,因此緩存的可操做空間很是大json

緩存的應用場景

一、每次都加載某個一樣的靜態文件 => 浪費帶寬,重複請求 => 讓瀏覽器使用本地緩存(協商緩存,返回304)數組

二、協商緩存仍是要和服務器通訊 => 依然存在有網絡請求 => 強制瀏覽器使用本地強緩存(返回200)瀏覽器

三、緩存要更新啊,兄弟,網絡請求都沒了,我咋知道啥時候要更新?=> 讓請求(header加上ETag)或者url的修改與文件內容關聯(文件名加哈希值)緩存

四、CTO大佬說,咱們買了阿里仍是騰訊的CDN,幾百G呢,用起來啊 => 把靜態資源和動態網頁分集羣部署,靜態資源部署到CDN節點上,網頁中引用的資源變成對應的部署路徑 => html中的資源引用和CDN上的靜態資源對應的url地址聯繫起來了 => 問題來了,更新的時候先上線頁面,仍是先上線靜態資源?(蠢,等到半天三四點啊,用戶都睡了,隨便你先上哪一個)

五、老闆說:咱們的產品未來是國際化的,不存在所謂的半夜三點 => GG,咋辦?=> 用非覆蓋式發佈啊,用文件的摘要信息來對資源文件進行重命名,把摘要信息放到資源文件發佈路徑中,這樣,內容有修改的資源就變成了一個新的文件發佈到線上,不會覆蓋已有的資源文件。上線過程當中,先全量部署靜態資源,再灰度部署頁面 (參考網上內容)

各種緩存

數據緩存

一、cookie: 一個用戶所請求的操做屬於一個會話,而另外一個用戶所請求的是另外一個會話,因爲http是無狀態的,一旦會話完畢就會關閉,這樣沒法經過會話保存所請求的內容。 一個用戶請求服務器,服務器如需保存用戶的信息,則返回的response加cookie信息,瀏覽器會將cookie保存在瀏覽器上,下次請求會將請求信息和cookie一塊兒發給瀏覽器,這樣服務器經過cookie信息識別用戶信息,甚至修改cookie信息,以此來辨認用戶狀態。

二、session: 和cookie不一樣的是,session是保存在服務器上的。服務器經過識別cookie帶來的sessin-id,來找到服務器上保存的用戶信息,以此來識別用戶。

當程序須要爲某個瀏覽器建立session信息的話: 一、程序首先檢查該請求是否攜帶sessionId.

二、攜帶sessionId的話程序會本身在服務器上查詢該sessionId,拿到session信息。若是查詢不到,會新建一個一個sessionId

三、請求未攜帶sessionId,程序會在附服務器上建立一個session,將此session的sessionId返回給瀏覽器。

缺點:在請求頭上,大小4k。

經常使用的配置屬性有如下幾個

Expires :cookie最長有效期

Max-Age:在 cookie 失效以前須要通過的秒數。(當Expires和Max-Age同時存在時,文檔中給出的是已Max-Age爲準,但是我本身用Chrome實驗的結果是取兩者中最長有效期的值)

Domain:指定 cookie 能夠送達的主機名。

Path:指定一個 URL 路徑,這個路徑必須出如今要請求的資源的路徑中才能夠發送 Cookie 首部

Secure:一個帶有安全屬性的 cookie 只有在請求使用SSL和HTTPS協議的時候纔會被髮送到服務器。

HttpOnly:設置了 HttpOnly 屬性的 cookie 不能使用 JavaScript 經由 Document.cookie 屬性、XMLHttpRequest 和 Request APIs 進行訪問,以防範跨站腳本攻擊(XSS)。

storage

一、sessionStorage:

sessionStorage存儲在瀏覽器上,存儲內容能夠是任何形式(包括:數組、圖片、json、樣式。。。)等。明文存儲,因此通常不會保存較敏感信息。當頁面關閉的時候不會保存。

二、localStorage:

同sessionStorage同樣,也是存儲在瀏覽器上,存儲內容形式多樣,明文存儲。可是當瀏覽器關閉的時候,信息仍然會存在。除非人爲刪除,不然理論上永遠存在。

二者存儲大小5M左右。

監聽storage事件 能夠經過監聽 window 對象的 storage 事件並指定其事件處理函數,當頁面中對 localStorage 或 sessionStorage 進行修改時,則會觸發對應的處理函數

window.addEventListener('storage',function(e){
   console.log('key='+e.key+',oldValue='+e.oldValue+',newValue='+e.newValue);
})
複製代碼

觸發事件的時間對象(e 參數值)有幾個屬性:

key : 鍵值。

oldValue : 被修改前的值。

newValue : 被修改後的值。

url : 頁面url。

storageArea : 被修改的 storage 對象。

HTTP Header緩存

良好的緩存能下降資源重複加載提高頁面加載速度。 緩存分爲強緩存和協商緩存

1、基本概述

一、請求原理

1)、瀏覽器加載資源的時候首先檢查請求頭的expires和cache-control來判斷有沒有強緩存,有的話直接使用強緩存。

2)、若是沒有命中強緩存,則向服務器發送請求,根據last-modified和etag來檢查是否有協商緩存,有的話返回304,直接使用協商緩存。

3)、未命中協商緩存的話則直接從服務器上拉取資源。

二、相同點

命中後都是從瀏覽器中直接拉取資源。

三、不一樣點

強緩存不發送請求到服務器,協商緩存則發請求到服務器。

2、強緩存

強緩存主要經過expier和cache-control來表示緩存時間和資源。

一、expire

expire是http1.0 提供的規範。它的值是一個GMT格式的絕對時間值。這表明expire失效的時間,在這個時間以前永遠有效。可是這個值是受到瀏覽器上本地時間影響的,若是瀏覽器和服務器時間不一致,則會致使緩存混亂。當cache-control: max-age和expire同時存在的時候,max-age優先級高。

二、cache-control

cache-control是http1.1提供的規範。利用max-age來判斷緩存時間,是一個相對值。例如cache-control: max-age=1000,則表示緩存在1000秒內有效。

cache-control經常使用的值:

no-cache:不使用本地緩存。須要使用緩存協商,先與服務器確認返回的響應是否被更改,若是以前的響應中存在ETag,那麼請求的時候會與服務端驗證,若是資源未被更改,則能夠避免從新下載。

no-store:直接禁止遊覽器緩存數據,每次用戶請求該資源,都會向服務器發送一個請求,每次都會下載完整的資源。

public:能夠被全部的用戶緩存,包括終端用戶和CDN等中間代理服務器。

private:只能被終端用戶的瀏覽器緩存,不容許CDN等中繼緩存服務器對其緩存。

Cache-Control與Expires能夠在服務端配置同時啓用,同時啓用的時候Cache-Control優先級高。

2、協商緩存

協商緩存就是由服務器來判斷緩存是否有效,瀏覽器和服務器之間協商一個標示,根據該標示來判斷是否使用緩存。 這個主要涉及到兩組header字段:Etag和If-None-Match、Last-Modified和If-Modified-Since

一、Etag和If-None-Match Etag/If-None-Match返回的是一個校驗碼。ETag能夠保證每個資源是惟一的,資源變化都會致使ETag變化。服務器根據瀏覽器上送的If-None-Match值來判斷是否命中緩存。

與Last-Modified不同的是,當服務器返回304 Not Modified的響應時,因爲ETag從新生成過,response header中還會把這個ETag返回,即便這個ETag跟以前的沒有變化。

二、Last-Modify/If-Modify-Since 瀏覽器第一次請求一個資源的時候,服務器返回的header中會加上Last-Modify,Last-modify是一個時間標識該資源的最後修改時間。

當瀏覽器再次請求該資源時,request的請求頭中會包含If-Modify-Since,該值爲緩存以前返回的Last-Modify。服務器收到If-Modify-Since後,根據資源的最後修改時間判斷是否命中緩存。

若是命中緩存,則返回304,而且不會返回資源內容,而且不會返回Last-Modify。

3、緩存流程圖

流程
其他緩存內容,下次在和你們一塊兒探討。
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息