HTTP緩存機制 & cookie/localStorage/sessionStorage

web緩存大致可以分為:數(shù)據(jù)庫數(shù)據(jù)緩存、服務(wù)器端緩存(代理服務(wù)器緩存、CDN緩存)、瀏覽器端緩存、web應(yīng)用層緩存。

其中,瀏覽器端緩存的機制種類:HTTP緩存機制、瀏覽器本地存儲(cookie 、localStorage、sessionStorage、webSQL、indexDB、……)如下圖所示:

瀏覽器本地存儲

本文主要著重講解瀏覽器本地存儲(cookie 、localStorage、sessionStorage) 以及 HTTP緩存機制。


瀏覽器本地存儲

Cookie

Cookie(或者Cookies),指某些網(wǎng)站為了辨別用戶身份而儲存在用戶本地終端(Client Side)上的數(shù)據(jù)(通常經(jīng)過加密)

  • cookie一般通過http請求中在頭部一起發(fā)送到服務(wù)器端。
  • 一條cookie記錄主要由鍵、值、域、過期時間、大小組成,一般用戶保存用戶的認證信息。
  • Cookie是為了解決HTTP無狀態(tài)的特性而出現(xiàn)的,也可以叫用戶識別機制。

sessionStorage 和 localStorage

Web Storage 是指 HTML5 的本地存儲 API sessionStorage 和 localStorage。

  • Web Storage 是通過存儲字符串的 Key/Value 對來提供的,并提供 5MB (不同瀏覽器可能不同,分 HOST)的存儲空間,如果數(shù)據(jù)存放超過最大限制會報錯,并移除最先保存的數(shù)據(jù)。
  • Web Storage 分為 sessionStorage 和 localStorage。localStorage 對象和 sessionStorage 對象使用方法基本相同,它們的區(qū)別在于作用的范圍不同。sessionStorage用來存儲與頁面相關(guān)的數(shù)據(jù),它在頁面關(guān)閉后無法使用。而 localStorage則持久存在,在頁面關(guān)閉后也可以使用

Cookie VS Web Storage

Cookie & Web Storage 異同點

Cookie VS Session

Cookie VS Session 異同點

HTTP緩存機制

概述

從緩存位置上來說分為四種,優(yōu)先級依次是:
Memory Cache、Service Worker Cache、Disk Cache、Push Cache


瀏覽器緩存
  • MemoryCache,是指存在內(nèi)存中的緩存。從優(yōu)先級上來說,它是瀏覽器最先嘗試去命中的一種緩存。從效率上來說,它是響應(yīng)速度最快的一種緩存。瀏覽器秉承的是“節(jié)約原則”,我們發(fā)現(xiàn),Base64 格式的圖片,幾乎永遠可以被塞進 memory cache,這可以視作瀏覽器為節(jié)省渲染開銷的“自保行為”;此外,體積不大的 JS、CSS 文件,也有較大地被寫入內(nèi)存的幾率——相比之下,較大的 JS、CSS 文件就沒有這個待遇了,內(nèi)存資源是有限的,它們往往被直接甩進磁盤。一旦我們關(guān)閉 Tab 頁面,內(nèi)存中的緩存也就被釋放了。
  • Service Worker, 是一種獨立于主線程之外的 Javascript 線程。它脫離于瀏覽器窗體,因此無法直接訪問 DOM。這樣獨立的個性使得 Service Worker 的“個人行為”無法干擾頁面的性能,這個“幕后工作者”可以幫我們實現(xiàn)離線緩存、消息推送和網(wǎng)絡(luò)代理等功能。我們借助 Service worker 實現(xiàn)的離線緩存就稱為 Service Worker Cache。
  • Disk Cache(HTTP Cache),Disk Cache 也就是存儲在硬盤中的緩存,讀取速度慢點,但是什么都能存儲到磁盤中,比之 Memory Cache 勝在容量和存儲時效性上。在所有瀏覽器緩存中,Disk Cache 覆蓋面基本是最大的。它會根據(jù) HTTP Header 中的字段判斷哪些資源需要緩存,哪些資源可以不請求直接使用,哪些資源已經(jīng)過期需要重新請求。并且即使在跨站點的情況下,相同地址的資源一旦被硬盤緩存下來,就不會再次去請求數(shù)據(jù)。絕大部分的緩存都來自 Disk Cache,關(guān)于 HTTP 的協(xié)議頭中的緩存字段,我們會在下文進行詳細介紹。它又分為強緩存和協(xié)商緩存。
  • Push Cache,Push Cache 是指 HTTP2 在 server push 階段存在的緩存。
    • Push Cache 是緩存的最后一道防線。瀏覽器只有在 Memory Cache、HTTP Cache 和 Service Worker Cache 均未命中的情況下才會去詢問 Push Cache。
    • Push Cache(推送緩存) 是一種存在于會話階段的緩存,當(dāng) session 終止時,緩存也隨之釋放。
    • 不同的頁面只要共享了同一個 HTTP2 連接,那么它們就可以共享同一個 Push Cache。

瀏覽器端的緩存規(guī)則

  • 新鮮度(過期機制):也就是緩存副本有效期。一個緩存副本必須滿足以下任一條件,瀏覽器會認為它是有效的,足夠新的,而直接從緩存中獲取副本并渲染:
    • 含有完整的過期時間控制頭信息(HTTP協(xié)議報頭),并且仍在有效期內(nèi)
    • 瀏覽器已經(jīng)使用過這個緩存副本,并且在一個會話中已經(jīng)檢查過新鮮度
  • 校驗值(驗證機制):服務(wù)器返回資源的時候有時在控制頭信息帶上這個資源的實體標(biāo)簽Etag(Entity Tag),它可以用來作為瀏覽器再次請求過程的校驗標(biāo)識。如過發(fā)現(xiàn)校驗標(biāo)識不匹配,說明資源已經(jīng)被修改或過期,瀏覽器需求重新獲取資源內(nèi)容。

瀏覽器緩存的控制

分別從新鮮度和校驗值兩個維度來規(guī)定瀏覽器是否可以直接使用緩存中的副本,還是需要去源服務(wù)器獲取更新的版本。


常見的與緩存有關(guān)的消息報頭
if (Cache-Control === no-store) {
  // 絕對禁止緩存,瀏覽器本地不會進行緩存,每次請求資源都要從服務(wù)器重新獲取。
 直接向服務(wù)器獲取資源(本地不緩存資源)
} else if (Cache-Control === no-cache) {
  // 設(shè)置了 no-cache 之后并不代表瀏覽器不緩存,而是在獲取緩存前要向服務(wù)器確認資源是否被更改。
 每次請求都向服務(wù)器確認資源是否被更改(本地緩存資源),走下面的協(xié)商緩存
} else if (本地未過期 => max-age || Expires) {
  使用瀏覽器本地緩存
} else { // 協(xié)商緩存
  if (ETag有值) {

      向服務(wù)器請求帶if-None-Match

      if (ETag與原來的一致) {
        返回304,直接使用本地緩存
      } else {
        返回200,獲取新資源
      }
  } else if (Last-modified有值) {

      向服務(wù)器請求帶if-Modified-Since

      if (Last-modified與原來的一致) {
        返回304,直接使用本地緩存
      } else {
        返回200,獲取新資源
      }
  } else {
      向服務(wù)器獲取新資源,返回200
 }
}

緩存流程

以上過程也可以被概括為三個階段:

  • 本地緩存階段(也稱強緩存):先在本地查找該資源,如果有發(fā)現(xiàn)該資源,而且該資源還沒有過期,就使用這一個資源,完全不會發(fā)送http請求到服務(wù)器;
  • 協(xié)商緩存階段(也稱弱緩存):如果在本地緩存找到對應(yīng)的資源,但是不知道該資源是否過期或者已經(jīng)過期,則發(fā)一個http請求到服務(wù)器,然后服務(wù)器判斷這個請求,如果請求的資源在服務(wù)器上沒有改動過,則返回304,讓瀏覽器使用本地找到的那個資源;
  • 緩存失敗階段:當(dāng)服務(wù)器發(fā)現(xiàn)請求的資源已經(jīng)修改過,或者這是一個新的請求(在本來沒有找到資源),服務(wù)器則返回該資源的數(shù)據(jù),并且返回200, 當(dāng)然這個是指找到資源的情況下,如果服務(wù)器上沒有這個資源,則返回404。

詳細信息——緩存有關(guān)的HTTP消息報頭

Cache-Control
  • max-age(單位為s)指定設(shè)置緩存最大的有效時間,定義的是時間長短。當(dāng)瀏覽器向服務(wù)器發(fā)送請求后,在max-age這段時間里瀏覽器就不會再向服務(wù)器發(fā)送請求了。
  • s-maxage(單位為s)同max-age,只用于共享緩存(比如CDN緩存)。比如,當(dāng)s-maxage=60時,在這60秒中,即使更新了CDN的內(nèi)容,瀏覽器也不會進行請求。也就是說max-age用于普通緩存,而s-maxage用于代理緩存。如果存在s-maxage,則會覆蓋掉max-age和Expires header。
  • no-cache 指定不緩存響應(yīng),表明資源不進行緩存,但是設(shè)置了 no-cache 之后并不代表瀏覽器不緩存,而是在獲取緩存前要向服務(wù)器確認資源是否被更改。因此有的時候只設(shè)置 no-cache 防止緩存還是不夠保險,還可以加上 private 指令,將過期時間設(shè)為過去的時間。(no-cache 繞開了瀏覽器:我們?yōu)橘Y源設(shè)置了 no-cache 后,每一次發(fā)起請求都不會再去詢問瀏覽器的緩存情況,而是直接向服務(wù)端去確認該資源是否過期,即走協(xié)商緩存的路線)
  • no-store 絕對禁止緩存,如果用了這個命令就是不會進行緩存每次請求資源都要從服務(wù)器重新獲取。(no-store 比較絕情,顧名思義就是不使用任何緩存策略。在 no-cache 的基礎(chǔ)上,它連服務(wù)端的緩存確認也繞開了,只允許你直接向服務(wù)端發(fā)送請求、并下載完整的響應(yīng)。)
Cache-Control與Expires

Cache-Control與 Expires的作用一致,都是指明當(dāng)前資源的有效期,控制瀏覽器是否直接從瀏覽器緩存取數(shù)據(jù)還是重新發(fā)請求到服務(wù)器取數(shù)據(jù)。只不過 Cache-Control的選擇更多,設(shè)置更細致,如果同時設(shè)置的話,其優(yōu)先級高于 Expires

public 與 private

public 與 private 是針對資源是否能夠被代理服務(wù)緩存而存在的一組對立概念。如果我們?yōu)橘Y源設(shè)置了 public,那么它既可以被瀏覽器緩存,也可以被代理服務(wù)器緩存;如果我們設(shè)置了 private,則該資源只能被瀏覽器緩存。private 為默認值。

Last-Modified與ETag

Etag是服務(wù)器自動生成或者由開發(fā)者生成的對應(yīng)資源在服務(wù)器端的唯一標(biāo)識符,能夠更加準(zhǔn)確的控制緩存。Last-Modified與ETag是可以一起使用的,服務(wù)器會優(yōu)先驗證ETag,一致的情況下,才會繼續(xù)比對Last-Modified,最后才決定是否返回304。

Last-Modified/ETag 與 Cache-Control/Expires
  • 配置 Last-Modified/ETag的情況下,瀏覽器再次訪問統(tǒng)一URI的資源,還是會發(fā)送請求到服務(wù)器詢問文件是否已經(jīng)修改,如果沒有,服務(wù)器會只發(fā)送一個304回給瀏覽器,告訴瀏覽器直接從自己本地的緩存取數(shù)據(jù);如果修改過那就整個數(shù)據(jù)重新發(fā)給瀏覽器;
  • Cache-Control/Expires則不同,如果檢測到本地的緩存還是有效的時間范圍內(nèi),瀏覽器直接使用本地副本,不會發(fā)送任何請求。兩者一起使用時, Cache-Control/Expires的優(yōu)先級要高,即當(dāng)本地副本根據(jù) Cache-Control/Expires發(fā)現(xiàn)還在有效期內(nèi)時,則不會再次發(fā)送請求去服務(wù)器詢問修改時間 Last-Modified或?qū)嶓w標(biāo)識 Etag了。
  • 一般情況下,兩者會配合一起使用,因為即使服務(wù)器設(shè)置緩存時間, 當(dāng)用戶點擊“刷新”按鈕時,瀏覽器會忽略緩存繼續(xù)向服務(wù)器發(fā)送請求,這時 Last-Modified/ETag將能夠很好利用304,從而減少響應(yīng)開銷。
有Last-Modified為什么還要有ETag?

HTTP1.1中Etag的出現(xiàn)主要是為了解決幾個 Last-Modified 比較難解決的問題:

  • Last-Modified 標(biāo)注的最后修改只能精確到秒級,如果某些文件在1秒鐘以內(nèi),被修改多次的話,它將不能準(zhǔn)確標(biāo)注文件的新鮮度
  • 如果某些文件會被定期生成,當(dāng)有時內(nèi)容并沒有任何變化,但 Last-Modified 卻改變了,導(dǎo)致文件沒法使用緩存
  • 有可能存在服務(wù)器沒有準(zhǔn)確獲取文件修改時間,或者與代理服務(wù)器時間不一致等情形
用戶操作行為與緩存的關(guān)系
用戶操作行為與緩存的關(guān)系

參考鏈接:
你必須懂的前端性能優(yōu)化
瀏覽器緩存機制全攻略
Web緩存相關(guān)知識整理
9大瀏覽器端緩存機制分析
深入理解瀏覽器的緩存機制

推薦文章:
前端開發(fā)之走進Vue.js(入門知識點)
《你不知道的javascript上卷》摘要(上)
《你不知道的javascript上卷》摘要(下)
Git使用總結(jié)
如何在Vue+Webpack下配置Stylelint
Highchart屬性筆記

原文:HTTP緩存機制 & cookie/localStorage/sessionStorage

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò)特有的延遲以及數(shù)據(jù)傳輸?shù)某杀荆萍s互聯(lián)網(wǎng)快速獲取Web資源。為此,HTTP協(xié)議引入緩存以空間換時間,使瀏覽器緩...
    大頭8086閱讀 3,091評論 2 12
  • 瀏覽器對于請求資源, 流程如圖所示: 可以看到瀏覽器的緩存機制分為兩個部分: 1、當(dāng)前緩存是否過期? 2、服務(wù)器中...
    zhoulujun閱讀 1,231評論 0 3
  • 參考《深入理解瀏覽器的緩存機制》進行整理 前言 緩存可以說是性能優(yōu)化中簡單高效的一種優(yōu)化方式了。一個優(yōu)秀的緩存策略...
    琢磨先生lf閱讀 750評論 1 1
  • 最近在項目中遇到了 IE瀏覽器因緩存問題未能成功向后端發(fā)送 GET類型請求 的bug,然后順藤摸瓜順便看了看緩存的...
    殖民_FE閱讀 789評論 0 1
  • 一、前言 緩存可以說是性能優(yōu)化中簡單高效的一種優(yōu)化方式了。一個優(yōu)秀的緩存策略可以縮短網(wǎng)頁請求資源的距離,減少延遲,...
    沉落的星星閱讀 395評論 0 0