談到頁面性能優化,緩存機制是其中非常重要的一環。緩存可以使頁面盡可能快地得到需要的文檔,具有減輕帶寬、降低服務的負荷、提高用戶體驗等功能。隨着高級瀏覽器,尤其是移動端的發展,可用的緩存范疇逐漸變大,簡單地將其分為三類:
一、Application Cache
這是H5中的新特性,可以將頁面資源緩存在本地,當頁面處於離線狀態下依然可以使用。使用方法很簡單,大致分為2步:
<html mainfest="mainfest.appcache">
CACHE MANIFEST # 23-01-2015 v0.1 /style.css /logo.gif /script.js NETWORK: * FALLBACK: /server/ /fallback.html
但是目前來說,離線存儲存在一些坑,曾經為了提高頁面性能,使用過該技術,帶來了很多問題,很快就刪除不再使用,簡單總結下目前離線存儲的特點:
- 每個包含manifest的網頁都會隱式添加到appCache中
- 一個文件找不到,整個appCache均被丟棄
- 即使online,也會使用appCache
- 更新頁面,appCache文件本身必須修改,才能讓瀏覽器刷新緩存文件
- 關於appCache的缺點可以查看文檔:App cache is a Douchebag using the application cache
二、localStorage
在移動端,這個API被廣泛使用,將一些長期不會發生改變的資源、歷史記錄保存在本地,通過在本地讀取加速網頁的訪問速度。需要注意的是localStorage只能存儲字符串,如果要緩存對象的話,需要通過JSON.stringify進行轉換,使用的時候再進行解析。常用API如下:
a.方法: getItem()、setItem()、key()、removeItem()、clear() b. 事件:storage function changeStorage() { window.addEventListener(’storage’, ) } 注意:storage事件只有在新窗口打開時,數據真正發生變化時才會觸發。也就是storage事件主要用於監聽localStorage/sessionStorage數據變化時,通知其他窗口或者標簽頁,實現數據變更通知。
三、HTTP
談到緩存會默認是HTTP緩存。首先看看HTTP緩存的大致流程:
在上圖展示了HTTP使用緩存的過程,其中(3)、(4)環節存在是否判斷,當均為true的時候才會直接使用本地緩存,其他情況請看下圖。但是還是存在下面兩個疑問:
- 如何判斷是否足夠新鮮
- 如何進行新鮮度驗證?
3.1 文檔新鮮度判斷
在HTTP response中可能存在兩個屬性:Expires、Cache-Control,這兩個屬性決定了文檔的有效期。如果當前時間滿足有效期,則直接讀取緩存文檔,返回給客戶端。
- 關於Expires: HTTP/1.0+定義該該屬性,存儲的是絕對日期,絕對日期依賴於計算機的時鍾時間。因為不同主機的時間中存在差異,所以使用Expires可能會造成一些問題。
- 關於Cache-Control:HTTP/1.1中增加了該屬性,該屬性定義的時間是相對時間,因此就沒有Expires的問題。Cache-Control存在如下幾個常用屬性
- no-cache: 除非對資源進行新鮮度檢驗,否則客戶端不會使用已緩存的資源
- no-store: 緩存應盡快從存儲器中刪除,因為可能存在敏感信息
- max-age=number: 緩存在number時間內是新鮮的
3.2 新鮮度檢驗
新鮮度檢驗有兩種方式:If-Modified-Since、If-No-Match,這兩個數據存在於HTTP request Header中,通過與服務器端的對比來判斷文檔是否發生改變。
- If-Modified-Since:基於時間的比較,response Header與之對應的是Last-Modified。
- If-No-Match:基於實體標簽進行比較,response Header與之對應的是Etag
3.3 緩存控制設置
通過在服務器端進行緩存的設置。以Apache為例,可以使用mod_headers、mod_expires、mod_cern_meta設置Expires或Cache-Control。