Web緩存相關知識整理

1、前言 

工做上遇到一個這樣的需求,一個H5頁面在APP端,若是勾選已讀狀態,則下次打開該連接,會跳過此頁面。用到了HTML5 的本地存儲 API 中的 localStorage做爲解決方案,回顧了下Web緩存的知識,感受本身瞭解得不夠多,因此想整理下,加深理解。javascript

Web緩存是指一個Web資源(如html頁面,圖片,js,數據等)存在於Web服務器和客戶端(瀏覽器)之間的副本。緩存會根據進來的請求保存輸出內容的副本;當下一個請求來到的時候,若是是相同的URL,緩存會根據緩存機制決定是直接使用副本響應訪問請求,仍是向源服務器再次發送請求。比較常見的就是瀏覽器會緩存訪問過網站的網頁,當再次訪問這個URL地址的時候,若是網頁沒有更新,就不會再次下載網頁,而是直接使用本地緩存的網頁。只有當網站明確標識資源已經更新,瀏覽器纔會再次下載網頁。css

2、web緩存的做用

  • 減小網絡帶寬消耗(當Web緩存副本被使用時,只會產生極小的網絡流量,能夠有效的下降運營成本。)
  • 下降服務器壓力(給網絡資源設定有效期以後,用戶能夠重複使用本地的緩存,減小對源服務器的請求,間接下降服務器的壓力。同時,搜索引擎的爬蟲機器人也能根據過時機制下降爬取的頻率,也能有效下降服務器的壓力。)
  • 減小網絡延遲,加開頁面打開速度。

3、web緩存的類型

在Web應用領域,Web緩存大體能夠分爲如下幾種類型:html

3.1 數據庫數據緩存

Web應用,特別是SNS類型的應用,每每關係比較複雜,數據庫表繁多,若是頻繁進行數據庫查詢,很容易致使數據庫不堪重荷。爲了提供查詢的性能,會將查詢後的數據放到內存中進行緩存,下次查詢時,直接從內存緩存直接返回,提供響應效率。好比經常使用的緩存方案有memcached等。前端

3.2 服務器端緩存

服務器端緩存包含代理服務器緩存和CDN緩存:html5

3.2.1 代理服務器緩存

代理服務器是瀏覽器和源服務器之間的中間服務器,瀏覽器先向這個中間服務器發起Web請求,通過處理後(好比權限驗證,緩存匹配等),再將請求轉發到源服務器。代理服務器緩存的運做原理跟瀏覽器的運做原理差很少,只是規模更大。能夠把它理解爲一個共享緩存,不僅爲一個用戶服務,通常爲大量用戶提供服務,所以在減小相應時間和帶寬使用方面頗有效,同一個副本會被重用屢次。常見代理服務器緩存解決方案有Squid等,這裏再也不詳述。java

3.2.2 CDN緩存

CDN(Content delivery networks)緩存,也叫網關緩存、反向代理緩存。CDN緩存通常是由網站管理員本身部署,爲了讓他們的網站更容易擴展並得到更好的性能。瀏覽器先向CDN網關發起Web請求,網關服務器後面對應着一臺或多臺負載均衡源服務器,會根據它們的負載請求,動態將請求轉發到合適的源服務器上。雖然這種架構負載均衡源服務器之間的緩存無法共享,但卻擁有更好的處擴展性。從瀏覽器角度來看,整個CDN就是一個源服務器。git

3.3 瀏覽器端緩存

瀏覽器緩存(Browser Caching)是瀏覽器端保存數據用於快速讀取或避免重複資源請求的優化機制,有效的緩存使用能夠避免重複的網絡請求和瀏覽器快速地讀取本地數據,總體上加速網頁展現給用戶。github

3.4 Web應用層緩存

應用層緩存指的是從代碼層面上,經過代碼邏輯和緩存策略,實現對數據,頁面,圖片等資源的緩存,能夠根據實際狀況選擇將數據存在文件系統或者內存中,減小數據庫查詢或者讀寫瓶頸,提升響應效率。web

接下來從Web前端的角度着重瞭解瀏覽器端緩存機制。sql

4、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頁面的節點中加入 標籤,代碼以下:

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">

 上述代碼的做用是告訴瀏覽器當前頁面不被緩存,每次訪問都須要去服務器拉取。使用上很簡單,但只有部分瀏覽器能夠支持,並且全部緩存代理服務器都不支持,由於代理不解析HTML內容自己。下面主要介紹HTTP協議定義的緩存機制。

4.1.2 HTTP協議定義的緩存機制

經過 HTTP 協議頭裏的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段來控制文件緩存的機制。這應該是 WEB 中最先的緩存機制了,是在 HTTP 協議中實現的,有點不一樣於 Dom Storage、AppCache 等緩存機制,但本質上是同樣的。能夠理解爲,一個是協議層實現的,一個是應用層實現的。

4.1.3 HTTP1.0 時代緩存字段詳解

  1. Pragma:設置頁面是否緩存,爲Pragma則緩存,no-cache則不緩存。
  2. Expires:有了Pragma來禁用緩存,天然也須要有個東西來啓用緩存和定義緩存時間,對http1.0而言,Expires就是作這件事的首部字段。 Expires的值對應一個GMT(格林尼治時間),好比Mon, 22 Jul 2002 11:12:01 GMT來告訴瀏覽器資源緩存過時時間,若是還沒過該時間點則不發請求。
    若是Pragma頭部和Expires頭部同時存在,則起做用的會是Pragma,須要注意的是,響應報文中Expires所定義的緩存時間是相對服務器上的時間而言的,其定義的是資源「失效時刻」,若是客戶端上的時間跟服務器上的時間不一致(特別是用戶修改了本身電腦的系統時間),那緩存時間可能就沒啥意義了。

4.1.4 HTTP1.1 時代緩存字段詳解

  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;這個纔是響應不被緩存的意思。
  1. 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。
  1. 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。
  1. 既生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. 小結
    (1) 瀏覽器第一次請求:
    如圖
(2) 瀏覽器第二次請求:
![如圖][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。
查看更多:戳這裏

4.4 Application Cache 機制

Application Cache(簡稱 AppCache)彷佛是爲支持 Web App 離線使用而開發的緩存機制。它的緩存機制相似於瀏覽器的緩存(Cache-Control 和 Last-Modified)機制,都是以文件爲單位進行緩存,且文件有必定更新機制。但 AppCache 是對瀏覽器緩存機制的補充,不是替代。
AppCache 的原理有兩個關鍵點:manifest 屬性和 manifest 文件。
W3C 官方的一個例子:

上面 HTML 文檔,引用外部一個 JS 文件和一個 GIF 圖片文件,在其 HTML 頭中經過 manifest 屬性引用了一個 appcache 結尾的文件(即manifest文件)。
緩存的結果是:咱們在 Google Chrome 瀏覽器中打開這個 HTML 連接,JS 功能正常,圖片也顯示正常。禁用網絡,關閉瀏覽器從新打開這個連接,發現 JS 工做正常,圖片也顯示正常。固然也有多是瀏覽緩存起的做用,咱們能夠在文件的瀏覽器緩存過時後,禁用網絡再試,發現 HTML 頁面也是正常的。
manifest 文件就是以 appcache 結尾的文件,是一個普通文件文件,列出了須要緩存的文件。
完整的 manifest 文件,如:

CACHE MANIFEST
# 2012-02-21 v1.0.0
/theme.css
/logo.gif
/main.js

NETWORK:
login.asp

FALLBACK:
/html/ /offline.html

瞭解更多:戳我

4.5 Indexed Database

IndexedDB 也是一種數據庫的存儲機制,但不一樣於已經再也不支持的 Web SQL Database。IndexedDB 不是傳統的關係數據庫,indexedDB中沒有表的概念,相似於 Dom Storage 的 key-value 的存儲方式,但功能更強大,且存儲空間更大。它的特色是:

  • 以key-value 的方式存取對象,能夠是任何類型值或對象,包括二進制。
  • 能夠對對象任何屬性生成索引,方便查詢。
  • 較大的存儲空間,默認推薦250MB(分 HOST),比 Dom Storage 的5MB要大的多。
  • 經過數據庫的事務(tranction)機制進行數據操做,保證數據一致性。
  • 異步的 API 調用,避免形成等待而影響體驗。

瞭解更多:資料1資料2

4.6 File System API

File System API 是 H5 新加入的存儲機制。它爲 Web App 提供了一個虛擬的文件系統,就像 Native App 訪問本地文件系統同樣。因爲安全性的考慮,這個虛擬文件系統有必定的限制。Web App 在虛擬的文件系統中,能夠進行文件(夾)的建立、讀、寫、刪除、遍歷等操做。

File System API 也是一種可選的緩存機制,和前面的 SQLDatabase、IndexedDB 和 AppCache 等同樣。File System API 有本身的一些特定的優點:

  • 能夠知足大塊的二進制數據( large binary blobs)存儲需求。
  • 能夠經過預加載資源文件來提升性能。
  • 能夠直接編輯文件。

瞭解更多:資料

5、總結

以前對web緩存沒有系統的認知,接觸過一兩點,不過也不是很懂。這兩天查看了許多資料,雖然看過以後理解得也不太深刻,不過有個總體的認知也好,後面本身遇到相關問題再細究。
參考資料:
一、九種瀏覽器端緩存機制知多少
二、瀏覽器緩存原理
三、Web緩存機制系列
四、Web 前端實現本地存儲
五、H5 緩存機制淺析 - 移動端 Web 加載性能優化
六、瀏覽器緩存機制
七、瀏覽器緩存機制詳解
八、透過瀏覽器看HTTP緩存
九、淺談瀏覽器http的緩存機制
十、瀏覽器緩存機制淺析

相關文章
相關標籤/搜索