h5 缓存机制
瀏覽器緩存機制
http緩存指的是: 當客戶端向服務器請求資源時,會先抵達瀏覽器緩存,如果瀏覽器有“要請求資源”的副本,就可以直接從瀏覽器緩存中提
取而不是從原始服務器中提取這個資源。
常見的http緩存只能緩存get請求響應的資源
瀏覽器緩存機制是指通過 HTTP 協議頭里的 Cache-Control/Expires和 Last-Modified/Etag等字段來控制文件緩存的機制。
總結
| http 1.1 | Cache-Control中的max-age | Last-Modified標識文件在服務器上的最新更新時間 | If-Modified-Since | 返回304,繼續使用緩存 | 返回200,同時返回最新的文件 | |
| Etag 對文件進行標識的特征字串 | If-None-Match | 返回304,繼續使用緩存 | 返回200,同時返回最新的文件 | 高 | ||
| http 1.0 | Expires 絕對的時間點 | 低 |
| 手動刷新 F5 | 認為緩存已經過期(可能緩存還沒有過期) | Cache-Control:max-age=0 |
| 強制刷新 Ctrl+F5 | 忽略本地的緩存(有緩存也會認為本地沒有緩存) | Cache-Control:no-cache(或 Pragma:no-cache兼容HTTP1.0) |
| 200(from cache) | expires/cache-control 沒失效 | 無變化 |
| 304 | last-modified/etag 失效 、F5、點擊刷新 | 無變化 |
| 200 | 本地無緩存、last-modified/etag 失效、 ctrl + F5 | 有變化 |
為什么有了Last-Modified ,還需要Etag?
Last-Modified:
- 修改精確到秒,1s內的改變不能標記
- 文件定期生成但內容不變,Last-Modified改變了,會導致不用緩存
- 當與代理服務器時間不一致時,會出問題
Etag:
- 服務器自動生成 / 開發者生成
- 對應著資源在服務器端的唯一標識符
- 更加準確的控制緩存
- 服務器會優先驗證Etag
- Yahoo建議分布式系統盡量關閉掉Etag
緩存分類
https://www.jianshu.com/p/227cee9c8d15
根據是否可以被單個或者多個用戶使用來分類:
-
私有緩存(瀏覽器級緩存)
- 私有緩存只能用于單獨的用戶:Cache-Control: Private
-
共享緩存(代理級緩存)
- 共享緩存可以被多個用戶使用:Cache-Control: Public
根據是否需要重新向服務器發起請求來分類,可分為(強制緩存,協商緩存)
| 存放位置 | 本地瀏覽器 | 本地瀏覽器 |
| 狀態碼 | 200 | 304 |
| 決定因素 | Pragma Cache-Control Expires | ETag/If-None-Match Last-Modified/If-Modified-Since |
| 是否與服務器交互 | 否 | 是 |
| 操作是否有效 | 強制刷新與F5刷新 – 無效; 地址欄回車、頁面鏈接跳轉、新開窗口、前進/后退 – 有效 | 強制刷新 – 無效; F5刷新 – 有效 地址欄回車、頁面鏈接跳轉、新開窗口、前進/后退 – 有效 |
在chrome瀏覽器中返回的200狀態會有兩種情況:
-
1、from memory cache (從內存中獲取/一般緩存更新頻率較高的js、圖片、字體等資源)
-
2、from disk cache (從磁盤中獲取/一般緩存更新頻率較低的js、css等資源)
這兩種情況是chrome自身的一種緩存策略,這也是為什么chrome瀏覽器響應的快的原因。其他瀏覽返回的是已緩存狀態,沒有標識是從哪獲取的緩存。
詳解
-
Cache-Control 控制文件在本地緩存有效時長。服務器響應標頭cache-control: no-cache, no-store, max-age=0, must-revalidate中的max-age表示時長,單位:秒
-
Last-Modified 標識文件在服務器上的最新更新時間
- 下次請求時,如果文件緩存過期,瀏覽器通過 If-Modified-Since 字段帶上這個時間,發送給服務器,由服務器比較時間戳來判斷文件是否有修改。
- 如果沒有修改,服務器返回304告訴瀏覽器繼續使用緩存
- 如果有修改,則返回200,同時返回最新的文件
Cache-Control 通常與 Last-Modified 一起使用。一個用于控制緩存有效時間,一個在緩存失效后,向服務查詢是否有更新。
-
Expires 與Cache-Control 同功能。Expires 的值是一個絕對的時間點,如:Expires: Thu, 10 Nov 2015 08:45:11 GMT,表示在這個時間點之前,緩存都是有效的。若客戶端與服務器相差時間大,誤差會很大
Expires 是 HTTP1.0 標準中的字段,Cache-Control 是 HTTP1.1 標準中新加的字段,功能一樣,都是控制緩存的有效時間。當這兩個字段同時出現時,Cache-Control 是高優化級的。
-
Etag 也是和 Last-Modified 一樣,對文件進行標識的字段。不同的是,Etag 的取值是一個對文件進行標識的特征字串。
- 在向服務器查詢文件是否有更新時,瀏覽器通過 If-None-Match 字段把特征字串發送給服務器,由服務器和文件最新特征字串進行匹配,來判斷文件是否有更新。
- 沒有更新回包304
- 有更新回包200
Etag 和 Last-Modified 可根據需求使用一個或兩個同時使用。兩個同時使用時,只要滿足基中一個條件,就認為文件沒有更新。
怎么使用緩存
一般需要緩存的資源有html頁面和其他靜態資源:
-
1、html頁面緩存的設置主要是在標簽中嵌入標簽,這種方式只對頁面有效,對頁面上的資源無效
- 1.1、html頁面禁用緩存的設置如下:
- 1.2、html設置緩存如下:
-
2、靜態資源的緩存一般是在web服務器上配置的,常用的web服務器有:nginx、apache
瀏覽器請求流程圖
瀏覽器第一次請求:
瀏覽器再次請求時:
Cookie與webStorage區別
總結
| cookie | http的同源請求中 | 設置的過期時間expires | 4k | 同源瀏覽器(相同的協議、相同的主機名、相同的端口) | 在客戶端與服務器端回傳 |
| localStorage | 本地瀏覽器 | 永久,除非手動清除 | 5M或更多(跟瀏覽器類型有關) | 同源瀏覽器 | 可指定路徑,支持事件通知機制,只能存儲獲取String類型的數據(JSON.stringify()、JSON.parse()) |
| sessionStorage | 本地瀏覽器 | 當次會話,結束后被清除 | 5M | 同一次會話(相同的協議、相同的主機名、相同的端口、同一窗口) | 支持事件通知機制,只能存儲獲取String類型的數據(JSON.stringify()、JSON.parse()) |
詳解
-
數據存儲
- cookie的數據始終在http的同源請求中存儲,數據可以在客戶端與服務器端進行回傳。
- webStorage的數據只能進行本地存儲,不能向服務器進行傳遞。
-
生命周期
- sessionStorage 會話級別的緩存,在當次會話結束后緩存數據被清除
- localStorage 永久緩存,直到被手動清除
- cookie 可以設置聲明周期,到該時間失效
-
存儲的數據量
- 每次http的請求都會攜帶cookie,所以 cookie存儲數據的大小要求不能超過 4k
- webStorage 數據因為只在本地進行緩存,對數據存儲量的可以達到 4-5M
-
作用域
- sessionStorage 作用在同一次會話之間,不在不同瀏覽器及同源之間進行共享。除了協議、主機名、端口外,還要求在同一窗口(也就是瀏覽器的標簽頁)下
- localStorage 作用在同源瀏覽器之間,只要在相同的協議、相同的主機名、相同的端口下,就能讀取/修改到同一份localStorage數據
- cookie 作用域也是在同源瀏覽器之間
-
cookie的數據還有路徑的概念,可以通過設置限制cookie只屬于某個路徑
-
可以使用 path 參數告訴瀏覽器 cookie 的路徑。默認情況下,cookie 屬于當前頁面
document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
-
-
webstorage 支持事件通知機制,可以將數據更新的通知發送給監聽者
- window.addEventListener(“storage”,doReaction,flag);
-
storage:表示對Storage(包括Localstorage和sessionStorage)進行監聽
-
doReaction:自定義函數,事件發生時回調,會接收一個StorageEvent類型的參數,包括:
- storageArea
- key(發生變化的key)
- oldValue(原值)
- newValue(新值)
- url(引發變化的URL)
-
flag:表示觸發時機,一般多使用false
webStorage 特點
| 減少網絡流量 | setItem(key, value) | 設置存儲內容 |
| 快速顯示數據 | getItem(key) | 讀取存儲內容,獲取到的數據都是String類型 |
| 臨時存儲 | removeItem(key) | 刪除鍵值為key的存儲內容 |
| 不影響網絡效能 | clear() | 清空所有存儲內容 |
-
webStorage 的好處
-
1、減少網絡流量:使用webstorage將數據保存在本地中,減少不必要的請求
-
2、快速顯示數據:從本地獲取數據比通過網絡從服務器獲取數據效率更高,因此網頁顯示也比較快
-
3、臨時存儲:很多時候數據只需在用戶瀏覽一組頁面期間使用,關閉窗口后數據就會丟失,使用sessionstorage 比較方便
-
4、不影響網絡效能:因為webstorage只作用在客戶端的瀏覽器,不會占用頻寬
-
離線應用 manifest
HTML5中我們可以輕松的構建一個離線(無網絡狀態)應用,只需要創建一個cache manifest文件。
-
優勢
- 1、可配置需要緩存的資源
- 2、網絡無連接應用仍可用
- 3、本地讀取緩存資源,提升訪問速度,增強用戶體驗
- 4、減少請求,緩解服務器負擔
-
緩存清單
- 一個普通文本文件,其中列出了瀏覽器應緩存以供離線訪問的資源,推薦使用.appcache為后綴名
- 例如我們創建了一個名為demo.appcache的文件,然后在需要應用緩存在頁面的根元素(html)添加屬性manifest="demo.appcache",路徑要保證正確。
-
manifest文件格式
- 1、首行必須是CACHE MANIFEST
- 2、每一行列出一個需要緩存的資源文件名。
- 3、NETWORK: 換行 白名單中的所有資源不會被緩存,在使用時將直接在線訪問,可使用通配符
- 4、CACHE: 換行 在白名單后還要補充需要緩存的資源,如.css、image、js等
- 5、FALLBACK: 換行 當被緩存的文件找不到時的備用資源
-
其它
- 1、CACHE: 可以省略,這種情況下將需要緩存的資源寫在CACHE MANIFEST
- 2、可以指定多個CACHE: NETWORK: FALLBACK:,無順序限制
- 3、注釋要另起一行,#表示注釋,只有當demo.appcache文件內容發生改變時或者手動清除緩存后,才會重新緩存。
- 4、chrome 可以通過chrome://appcache-internals/工具和離線(offline)模式來調試管理應用緩存
html頁面引入上面的manifest文件:
<!DOCTYPE HTML> <html manifest="calender.manifest"><head>...</head><body>...</body> </html>1、自動更新
cache manifest 文件本身發生變化時更新緩存,,而 cache manifest 中的 資源文件 發生變化并不會觸發更新。
2、手動更新
使用 window.applicationCache 的接口 手動更新緩存:
if(window.applicationCache.status == window.applicationCache.UPDATEREADY) {window.applicationCache.update(); }總結
- 上一篇: 前端学习(680):switch注意事项
- 下一篇: 前端学习(1360) :学生档案信息管理