Web緩存相關知識整理
一、前言
工作上遇到一個這樣的需求,一個H5頁面在APP端,如果勾選已讀狀態,則下次打開該鏈接,會跳過此頁面。用到了HTML5 的本地存儲 API 中的 localStorage作為解決方案,回顧了下Web緩存的知識,感覺自己了解得不夠多,所以想整理下,加深理解。
Web緩存是指一個Web資源(如html頁面,圖片,js,數據等)存在於Web伺服器和客戶端(瀏覽器)之間的副本。緩存會根據進來的請求保存輸出內容的副本;當下一個請求來到的時候,如果是相同的URL,緩存會根據緩存機制決定是直接使用副本響應訪問請求,還是向源伺服器再次發送請求。比較常見的就是瀏覽器會緩存訪問過網站的網頁,當再次訪問這個URL地址的時候,如果網頁沒有更新,就不會再次下載網頁,而是直接使用本地緩存的網頁。只有當網站明確標識資源已經更新,瀏覽器才會再次下載網頁。
二、web緩存的作用
- 減少網路帶寬消耗(當Web緩存副本被使用時,只會產生極小的網路流量,可以有效的降低運營成本。)
- 降低伺服器壓力(給網路資源設定有效期之後,用戶可以重複使用本地的緩存,減少對源伺服器的請求,間接降低伺服器的壓力。同時,搜索引擎的爬蟲機器人也能根據過期機制降低爬取的頻率,也能有效降低伺服器的壓力。)
- 減少網路延遲,加開頁面打開速度。
三、web緩存的類型
在Web應用領域,Web緩存大致可以分為以下幾種類型:
3.1 資料庫數據緩存Web應用,特別是SNS類型的應用,往往關係比較複雜,資料庫表繁多,如果頻繁進行資料庫查詢,很容易導致資料庫不堪重荷。為了提供查詢的性能,會將查詢後的數據放到內存中進行緩存,下次查詢時,直接從內存緩存直接返回,提供響應效率。比如常用的緩存方案有memcached等。
3.2 伺服器端緩存
伺服器端緩存包含代理伺服器緩存和CDN緩存:
3.2.1 代理伺服器緩存
代理伺服器是瀏覽器和源伺服器之間的中間伺服器,瀏覽器先向這個中間伺服器發起Web請求,經過處理後(比如許可權驗證,緩存匹配等),再將請求轉發到源伺服器。代理伺服器緩存的運作原理跟瀏覽器的運作原理差不多,只是規模更大。可以把它理解為一個共享緩存,不只為一個用戶服務,一般為大量用戶提供服務,因此在減少相應時間和帶寬使用方面很有效,同一個副本會被重用多次。常見代理伺服器緩存解決方案有Squid等,這裡不再詳述。
3.2.2 CDN緩存
CDN(Content delivery networks)緩存,也叫網關緩存、反向代理緩存。CDN緩存一般是由網站管理員自己部署,為了讓他們的網站更容易擴展並獲得更好的性能。瀏覽器先向CDN網關發起Web請求,網關伺服器後面對應著一台或多台負載均衡源伺服器,會根據它們的負載請求,動態將請求轉發到合適的源伺服器上。雖然這種架構負載均衡源伺服器之間的緩存沒法共享,但卻擁有更好的處擴展性。從瀏覽器角度來看,整個CDN就是一個源伺服器。
3.3 瀏覽器端緩存
瀏覽器緩存(Browser Caching)是瀏覽器端保存數據用於快速讀取或避免重複資源請求的優化機制,有效的緩存使用可以避免重複的網路請求和瀏覽器快速地讀取本地數據,整體上加速網頁展示給用戶。
3.4 Web應用層緩存
應用層緩存指的是從代碼層面上,通過代碼邏輯和緩存策略,實現對數據,頁面,圖片等資源的緩存,可以根據實際情況選擇將數據存在文件系統或者內存中,減少資料庫查詢或者讀寫瓶頸,提高響應效率。
接下來從Web前端的角度著重了解瀏覽器端緩存機制。
四、web緩存之瀏覽器端緩存淺析根據標準,到目前為止,H5 一共有6種緩存機制,有些是之前已有,有些是 H5 才新加入的。
1. 瀏覽器緩存機制
2. Dom Storgage(Web Storage)存儲機制
3. Web SQL Database 存儲機制
4. Application Cache(AppCache)機制
5. Indexed Database (IndexedDB)
6. File System API
4.1 瀏覽器緩存機制4.1.1 非HTTP協議定義的緩存機制
瀏覽器緩存機制,其實主要就是HTTP協議定義的緩存機制(如: Expires; Cache-control等)。但是也有非HTTP協議定義的緩存機制,如使用HTML Meta 標籤,Web開發者可以在HTML頁面的
節點中加入標籤,代碼如下:
上述代碼的作用是告訴瀏覽器當前頁面不被緩存,每次訪問都需要去伺服器拉取。使用上很簡單,但只有部分瀏覽器可以支持,而且所有緩存代理伺服器都不支持,因為代理不解析HTML內容本身。下面主要介紹HTTP協議定義的緩存機制。
4.1.2 HTTP協議定義的緩存機制通過 HTTP 協議頭裡的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等欄位來控制文件緩存的機制。這應該是 WEB 中最早的緩存機制了,是在 HTTP 協議中實現的,有點不同於 Dom Storage、AppCache 等緩存機制,但本質上是一樣的。可以理解為,一個是協議層實現的,一個是應用層實現的。
4.1.3 HTTP1.0 時代緩存欄位詳解
- Pragma:設置頁面是否緩存,為Pragma則緩存,no-cache則不緩存。
- Expires:有了Pragma來禁用緩存,自然也需要有個東西來啟用緩存和定義緩存時間,對http1.0而言,Expires就是做這件事的首部欄位。 Expires的值對應一個GMT(格林尼治時間),比如Mon, 22 Jul 2002 11:12:01 GMT來告訴瀏覽器資源緩存過期時間,如果還沒過該時間點則不發請求。
如果Pragma頭部和Expires頭部同時存在,則起作用的會是Pragma
,需要注意的是,響應報文中Expires所定義的緩存時間是相對伺服器上的時間而言的,其定義的是資源「失效時刻」,如果客戶端上的時間跟伺服器上的時間不一致(特別是用戶修改了自己電腦的系統時間),那緩存時間可能就沒啥意義了。
4.1.4 HTTP1.1 時代緩存欄位詳解
Cache-Control: 針對上述的「Expires時間是相對伺服器而言,無法保證和客戶端時間統一」的問題,http1.1新增了 Cache-Control 來定義緩存過期時間。注意:若報文中同時出現了 Expires 和 Cache-Control,則以 Cache-Control 為準。
(1) 最常見的,比如伺服器回包:Cache-Control:max-age=600 表示文件在本地應該緩存,且有效時長是600秒(從發出請求算起)。在接下來600秒內,如果有請求這個資源,瀏覽器不會發出 HTTP 請求,而是直接使用本地緩存的文件。
(2) Cache-Control: no-cache;這個很容易讓人產生誤解,使人誤以為是響應不被緩存。實際上她是會被緩存的,只不過每次在向客戶端(瀏覽器)提供響應數據時,緩存都要向伺服器評估緩存響應的有效性。
(3) Cache-Control: no-store;這個才是響應不被緩存的意思。 Last-Modified/If-Modified-Since:
(1) Last-Modified:標示這個響應資源的最後修改時間。web伺服器在響應請求時,告訴瀏覽器資源的最後修改時間。
(2) If-Modified-Since:當資源過期時(使用Cache-Control標識的max-age),發現資源具有Last-Modified聲明,則再次向web伺服器請求時帶上頭 If-Modified-Since,表示請求時間。web伺服器收到請求後發現有頭If-Modified-Since 則與被請求資源的最後修改時間進行比對。若最後修改時間較新,說明資源又被改動過,則響應整片資源內容(寫在響應消息包體內),HTTP 200;若最後修改時間較舊,說明資源無新修改,則響應HTTP 304 (無需包體,節省瀏覽),告知瀏覽器繼續使用所保存的cache。
Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。
(1) Etag:web伺服器響應請求時,告訴瀏覽器當前資源在伺服器的唯一標識(生成規則由伺服器覺得)。Apache中,ETag的值,默認是對文件的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後得到的。
(2) If-None-Match:當資源過期時(使用Cache-Control標識的max-age),發現資源具有Etage聲明,則再次向web伺服器請求時帶上頭If-None-Match (Etag的值)。web伺服器收到請求後發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定返回200或304。
既生Last-Modified何生Etag?
你可能會覺得使用Last-Modified已經足以讓瀏覽器知道本地的緩存副本是否足夠新,為什麼還需要Etag(實體標識)呢?HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題:
(1) Last-Modified標註的最後修改只能精確到秒級,如果某些文件在1秒鐘以內,被修改多次的話,它將不能準確標註文件的修改時間。
(2) 如果某些文件會被定期生成,當有時內容並沒有任何變化,但Last-Modified卻改變了,導致文件沒法使用緩存。
(3) 有可能存在伺服器沒有準確獲取文件修改時間,或者與代理伺服器時間不一致等情形。
Etag是伺服器自動生成或者由開發者生成的對應資源在伺服器端的唯一標識符,能夠更加準確的控制緩存。Last-Modified與ETag是可以一起使用的,伺服器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最後才決定是否返回304。 小結
(1) 瀏覽器第一次請求:
(2) 瀏覽器第二次請求:
4.2 Dom Storage 存儲機制
DOM Storage 是指 HTML5 的本地存儲 API sessionStorage 和 localStorage。在介紹HTML5本地存儲之前,先來看一看前面幾個存儲方式的概念。
(1) HTTP Cookie: Cookie是為了解決HTTP無狀態的特性而出現的,也可以叫用戶識別機制。常用的用戶識別機制包括:
- 承載用戶信息的HTTP首部
- 客戶端IP地址追蹤技術,通過用戶的IP地址對其進行識別
- 用戶登錄,用認證機制來識別用戶
- 胖URL,一種在URL中嵌入識別信息的技術
- cookie,一種強大且高效的持久身份識別技術
對於購物網站而言,cookie是非常重要的,為了實現購物車功能,把已選物品加入cookie,可以實現不同頁面之間數據的同步,同時在提交訂單的時候又會把這些cookie傳到後台,大大方便了前後端開發。 設置cookie:
function setCookie(name, value, options) {
var expires = options.expires;
var path = options.path;
var domain = options.domain;
var secure = options.secure;
// 緩存時間轉為日期對象
if (typeof expires === "number") {
expires = new Date(new Date.getTime + expires * 864e+5); // 緩存時間單位:天
}
document.cookie =
name + "=" + escape(value) +
(expires ? "; expires=" + expires.toUTCString : "") +
(path ? "; path=" + path : "") +
(domain ? "; domain=" + domain : "") +
(secure ? "; secure" : "");
return true;
}
獲取cookie:
function getCookie(name) {
var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
if (arr !== null) {
return unescape(arr[2]);
}
// return null;
return "";
}
(2) userData是微軟在上世紀90年代的瀏覽器大戰時推出的本地存儲方案,藉助DHTML的behaviour屬性來存儲本地數據, 允許每個頁面最多存儲64K數據,每個站點最多640K數據,userData的缺點顯而易見,它不是Web標準的一部分,除非你的程序只需要支持IE, 否則它基本沒什麼用處。
(3) Flash cookie的名字有些誤導,它實際上和HTTP cookie並不是一回事,或許它的名字應該叫做"Flash本地存儲」,Flash cookie默認允許每個站點存儲不超過100K的數據,如果超出了,Flash會自動向用戶請求更大的存儲空間,藉助Flash的 ExternalInterface介面,你可以很輕鬆地通過Javascript操作Flash的本地存儲。Flash的問題很簡單,就是因為它是 Flash。
(4) Gears是Google在07年發布的一個開源瀏覽器插件,旨在改進各大瀏覽器的兼容性,Gears內置了一個基於SQLite的嵌入式 SQL資料庫,並提供了統一API對資料庫進行訪問,在取得用戶授權之後,每個站點可以在SQL資料庫中存儲不限大小的數據,Gears的問題就是 Google自己都已經不用它了。
(5) HTML5 的本地存儲 API sessionStorage 和 localStorage
Dom Storage 是通過存儲字元串的 Key/Value 對來提供的,並提供 5MB (不同瀏覽器可能不同,分 HOST)的存儲空間(Cookies 才 4KB)。另外 Dom Storage 存儲的數據在本地,不像 Cookies,每次請求一次頁面,Cookies 都會發送給伺服器。
DOM Storage 分為 sessionStorage 和 localStorage。localStorage 對象和 sessionStorage 對象使用方法基本相同,它們的區別在於作用的範圍不同。sessionStorage 用來存儲與頁面相關的數據,它在頁面關閉後無法使用。而 localStorage 則持久存在,在頁面關閉後也可以使用。
簡單用法:
var name = sessionStorage.setItem("name","wangjuan");
alert(sessionStorage.getItem("name"));
並不是所有的瀏覽器都支持這兩個對象。在沒有原生支持localStorage的瀏覽器中使用時,MDN給出了兼容代碼:https://developer.mozilla.org/zh-CN/docs/Web/Guide/API/DOM/Storage#localStorage
不同瀏覽器對於這兩種用法的差異的兼容代碼可參考: https://github.com/mortzdk/localStorage
4.3 Web SQL存儲機制H5 也提供基於 SQL 的資料庫存儲機制,用於存儲適合資料庫的結構化數據。根據官方的標準文檔,Web SQL Database 存儲機制不再推薦使用,將來也不再維護,而是推薦使用 AppCache 和 IndexedDB。
※WebService入門實例教程
※Spring Boot的properties配置文件讀取
※藍橋杯 最短路徑問題
※一不小心,陷入TCP的性能問題
TAG:科技優家 |
※一篇文章理解 Web 緩存
※你真的理解 Integer 的緩存問題嗎?
※清理設備垃圾功能改版,有效清理 iPhone 緩存
※Linux內存管理中緩存失效漏洞分析及利用
※iPhone手機清理緩存小技巧,很簡單我教你
※redis緩存過期策略,監聽redis緩存
※Redis緩存技術應用
※企鵝FM中怎麼將緩存清理 企鵝FM緩存清理的方法
※redis獲取與設置用戶緩存信息
※技術解析 | Web緩存欺騙測試
※iPhone專屬,緩存清理、電池壽命查看
※Web緩存投毒實戰
※vivo Z1如何清理應用緩存?學會這三種方法都能輕鬆搞定!
※Spark調優的關鍵—RDD Cache緩存使用詳解
※J2Cache 和普通緩存框架有何不同,它解決了什麼問題?
※基於redis分散式緩存實現
※PB級數據持久化緩存系統——lest
※Python+Memcached:在分散式應用程序中實現高效緩存
※HashCache:低內存緩存存儲系統
※Centos 7利用內存優化磁碟緩存讀寫速度