導航
[深入01] 執(zhí)行上下文
[深入02] 原型鏈
[深入03] 繼承
[深入04] 事件循環(huán)
[深入05] 柯里化 偏函數(shù) 函數(shù)記憶
[深入06] 隱式轉換 和 運算符
[深入07] 瀏覽器緩存機制(http緩存機制)
[深入08] 前端安全
[深入09] 深淺拷貝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模塊化
[深入13] 觀察者模式 發(fā)布訂閱模式 雙向數(shù)據(jù)綁定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手寫Promise
[深入20] 手寫函數(shù)
[部署01] Nginx
[部署02] Docker 部署vue項目
[部署03] gitlab-CI
[源碼-webpack01-前置知識] AST抽象語法樹
[源碼-webpack02-前置知識] Tapable
[源碼-webpack03] 手寫webpack - compiler簡單編譯流程
[源碼] Redux React-Redux01
[源碼] axios
[源碼] vuex
[源碼-vue01] data響應式 和 初始化渲染
[源碼-vue02] computed 響應式 - 初始化,訪問,更新過程
緩存的重要性
- 一個優(yōu)秀的緩存策略,可以縮短網(wǎng)頁請求資源的距離,減少延遲,緩存文件可以重復利用所以還可以減少帶寬,降低網(wǎng)路負荷
瀏覽器緩存
- 瀏覽器啟用緩存的優(yōu)點:減少頁面加載時間,減少服務器負載
- <font color=red>瀏覽器是否使用緩存,緩存多久,是由服務器控制的</font>
- 即服務器響應的 <font color=red>響應頭</font> 中,某些字段指明了緩存的關鍵信息
- 通用首部字段
- 請求和響應都能用的字段
- Cache-Control
- 請求首部字段
- If-None-Match
- If-Modified-Since
- 響應首部字段
- ETag
- 實體首部字段
- Expires
- Last-Modified
- 瀏覽器緩存的分類
- <font color=red>強緩存</font> 和 <font color=red>協(xié)商緩存</font>
強緩存
- <font color=red>Expires</font>, <font color=red>Cache-Control</font>
- 返回的狀態(tài)碼 200
- <font color=red>network => size =>
會顯示 from-cache (from-disk-cache),(from-memory-cache)</font> - 強緩存的實現(xiàn):通過( <font color=red>Expires</font> ) 或者 ( <font color=red>Cache-Control</font> ) 這兩個 ( <font color=red>http response header</font> ) 來實現(xiàn)的,他們用都是用來表示資源在客服端存在的 <font color=red>有效期</font>
Expires
- http1.0提出,響應頭中的一個字段,絕對時間,用GMT格式的字符串表示
- <font color=red>注意:expires是和瀏覽器本地的時間做對比,是一個絕對時間點,是一個GMT時間</font>
- Expires是優(yōu)化中最理想的情況,因為它根本不會產(chǎn)生請求,所以后端也就無需考慮查詢快慢
- Expires的原理
Expires的原理
1. 瀏覽器第一次向服務器請求資源,瀏覽器在請求資源的同時,在responder響應頭中加上Expires字段
2. 瀏覽器在接收到這個資源后,將這個資源和所有response header一起緩存起來
- 所以,緩存命中的請求返回的header并不是來自服務器,而是來自之前緩存的header
3. 瀏覽器再次請求這個資源時,先從緩存中尋找,找到這個資源后,拿出Expires跟當前的請求時間做比較
- 如果當前請求時間,在Expires指定的時間之前,就能命中強緩存,否則不能
- 注意:Expires是和瀏覽器本地時間作對比
4. 如果未命中緩存,則瀏覽器直接從服務器獲取資源,并更新response header中的Expires
- expires是較老的強緩存管理header,<font color=red>是服務器返回的一個絕對時間</font>,在服務器時間與客服端時間相差較大時,Expires緩存管理容易出問題(比如:隨便修改客戶端時間,就能影響命中結果),所以在http1.1中,提出了新的header => Cache-Control,一個相對時間,以秒為單位,用數(shù)值表示
Cache-Control
- http1.1提出,響應頭中的一個字段,相對時間,以秒為單位,用數(shù)值表示
- <font color=red>注意:Cache-Control也是和瀏覽器本地時間做對比,以秒為單位的時間段</font>
- Cache-Control可以指定:<font color=red>public</font> 和 <font color=red>private</font>
- <font color=red>private</font>:
表示該資源僅僅屬于發(fā)出請求的最終用戶,這將禁止中間服務器(如代理服務器)緩存此類資源,對于包含用戶個人信息的文件,可以設置private - <font color=red>public</font>:
允許所有服務器緩存該資源 - no-cache:使用協(xié)商緩存
- no-store:不使用緩存
- max-age: 123123 // 一個時間段,單位是s
- <font color=red>private</font>:
- <font color=red>Cache-control: no-cache,private,max-age=123123</font>
- Cache-Control的原理
Cache-Control的原理
1. 瀏覽器第一次向服務器請求資源,服務器在返回資源的同時,在responder的header中加上Cache-Control字段
2. 瀏覽器在接收到這個資源后,會將這個資源和所有的response header一起緩存起來
- 所以,緩存命中的請求返回的header并不是來自服務器,而是來自之前緩存的header
3. 瀏覽器再次請求這個資源時,先從緩存中尋找,找到這個資源后,拿出Cache-Control和當前請求的時間做比較
- 如果當前請求時間,在Cache-Control表示的時間段內,就能命中強緩存,否則不能
4. 如果緩存未命中,則瀏覽器直接從服務器獲取資源,并更新response header中的 Cache-Control
強緩存Expires和Cache-Control總結
- Expires和Cache-Control可以開啟一個,也可以同時開啟
- 當Expires和Cache-Control同時開啟時,Cache-Control優(yōu)先級高于Expires
- Cache-Control可以指定private和public,表示是否允許中間服務器緩存該資源
- expires是一個用GMT時間表示的時間點,Cach-Control是用秒表示的時間段,都是和瀏覽器本地時間做對比
協(xié)商緩存
- <font color=red>Last-Modified(If-Modified-Since)</font>,<font color=red>ETag(If-None-Match)</font>
- 返回狀態(tài)碼 304
- 協(xié)商緩存的原理:<font color=red>當瀏覽器對某個資源的請求沒有命中強緩存,就會發(fā)一個請求到服務器,驗證協(xié)商緩存是否命中</font>,如果協(xié)商緩存命中,請求響應返回的http狀態(tài)為304,并且會顯示一個Not Modified的字符串表示資源未被修改
- modified: 是修改的意思
Last-Modified 和 If-Modified-Since
- Last-Modified和If-Modified-Since都是根據(jù) <font color=red>服務器時間</font> 返回的header
- 響應頭:Last-Modified
- 請求頭:If-Modified-Since
- 原理
Last-Modified If-None-Match
1. 瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在response的header加上Last-Modified的header
- 這個header表示這個資源在服務器上的最后修改時間
2. 瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-Modified-Since的header
- 這個header的值就是上一次請求時返回的Last-Modified的值
3. 服務器再次收到資源請求時,根據(jù)瀏覽器傳過來If-Modified-Since和資源在服務器上的最后修改時間判斷資源是否有變化
- 如果沒有變化則返回304 Not Modified,但是不會返回資源內容;
- 如果有變化,就正常返回資源內容。
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// 當服務器返回304 Not Modified的響應時,response header中不會再添加Last-Modified的header
// 因為既然資源沒有變化,那么Last-Modified也就不會改變
4. 瀏覽器收到304的響應后,就會從緩存中加載資源
5. 如果協(xié)商緩存沒有命中,瀏覽器直接從服務器加載資源時,Last-Modified Header在重新加載的時候會被更新
- 下次請求時,If-Modified-Since會啟用上次返回的Last-Modified值
ETag 和 If-None-Match
- <font color=red>只要資源有變化ETag這個字符串就不一樣,和修改時間沒有關系,所以很好的補充了Last-Modified的問題</font>
- 響應頭:ETag
- 請求頭:If-None-Match
- 原理
ETag 和 If-None-Match
1. 瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在response的header加上ETag的header
- 這個header是服務器根據(jù)當前請求的資源生成的一個唯一標識,這個唯一標識是一個字符串
- 只要資源有變化這個串就不同,跟最后修改時間沒有關系,所以能很好的補充Last-Modified的問題
2. 瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-None-Match的header,
- 這個header的值就是上一次請求時返回的ETag的值
3. 服務器再次收到資源請求時,根據(jù)瀏覽器傳過來If-None-Match然后再根據(jù)資源生成一個新的ETag
- 如果沒有變化則返回304 Not Modified,但是不會返回資源內容
- 如果有變化,就正常返回資源內容。
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// 與Last-Modified不一樣的是,當服務器返回304 Not Modified的響應時
// 由于ETag重新生成過,response header中還會把這個ETag返回,即使這個ETag跟之前的沒有變化
4. 瀏覽器收到304的響應后,就會從緩存中加載資源。
Last-Modified(If-Modified-Since) 和 ETag(If-None-Match) 的區(qū)別
- ETag的優(yōu)勢
- ETag和Last-Modified非常相似,都是用來判斷一個參數(shù),從而決定是否啟用緩存。
但是ETag相對于Last-Modified也有其優(yōu)勢,可以更加準確的判斷文件內容是否被修改,從而在實際操作中實用程度也更高。
強緩存和協(xié)商緩存的區(qū)別
- 協(xié)商緩存跟強緩存不一樣,強緩存不發(fā)請求到服務器,所以有時候資源更新了瀏覽器還不知道,但是協(xié)商緩存會發(fā)請求到服務器,所以資源是否更新,服務器肯定知道。
- 大部分web服務器都默認開啟協(xié)商緩存,而且是同時啟用Last-Modified,If-Modified-Since和ETag、If-None-Match
- Last-Modified,If-Modified-Since和ETag、If-None-Match一般都是同時啟用,這是為了處理Last-Modified不可靠的情況
- // 分布式系統(tǒng)里多臺機器間文件的Last-Modified必須保持一致,以免負載均衡到不同機器導致比對失敗
- // 分布式系統(tǒng)盡量關閉掉ETag(每臺機器生成的ETag都會不一樣)
瀏覽器緩存判斷的流程
- 第一次正常請求后,緩存了資源和所有header的前提下
- 在資源緩存后,在緩存過期失效之前,如果再次請求該資源,<font color=red>默認先檢查強緩存</font>
- 強緩存命中,則直接讀取
- 未命中強緩存,則發(fā)送請求到服務器,<font color=red>再檢查是否命中協(xié)商緩存</font>
- 未命中強緩存,再發(fā)請求到服務器檢查是否命中協(xié)商緩存
- 協(xié)商緩存命中,則告訴瀏覽器還是可以從緩存讀取
- 未命中協(xié)商緩存,才從服務器返回最新的資源
image