html5 客户端数据缓存机制,深入理解HTML5离线缓存机制
TML5提供了一種離線應用緩存機制,使得網頁應用可以離線使用,這種機制在移動端瀏覽器上支持度非常廣,所有版本的android和ios瀏覽器都能很好的支持。我們可以放心的使用該特性來加速移動端頁面的訪問速度。
開啟離線緩存的步驟也非常簡單:
(1) 準備緩存清單文件(menifest text/cache-manifest),用于描述頁面需要緩存的資源列表
(2) 在需要離線使用的頁面中添加menifest屬性,用于指定緩存清單文件的路徑
讓我們首先理解瀏覽器實現離線緩存的詳細步驟,然后探討使用離線緩存加速移動端網頁訪問速度的方案。
1. 下載/更新緩存的詳細步驟
(1)當瀏覽器訪問一個包含 manifest 特性的文檔時,如果應用緩存不存在,瀏覽器會加載文檔,然后獲取所有在清單文件中列出的文件,生成應用緩存的第一個版本。
(2)對該文檔的后續訪問會使瀏覽器直接從應用緩存(而不是服務器)中加載文檔與其他在清單文件中列出的資源。此外,瀏覽器還會向 window.applicationCache 對象發送一個 checking 事件,在遵循合適的 HTTP 緩存規則前提下,獲取清單文件。
(3)如果當前緩存的清單副本是最新的,瀏覽器將向 applicationCache 對象發送一個 noupdate 事件,到此,更新過程結束。注意,如果你在服務器修改了任何緩存資源,同時也應該修改清單文件,這樣瀏覽器才能知道它需要重新獲取資源。
(4)如果清單文件已經改變,文件中列出的所有文件—也包括通過調用 applicationCache.add() 方法添加到緩存中的那些文件—會被獲取并放到一個臨時緩存中,遵循適當的 HTTP 緩存規則。對于每個加入到臨時緩存中的文件,瀏覽器會向 applicationCache 對象發送一個 progress 事件。如果出現任何錯誤,瀏覽器會發送一個 error 事件,并暫停更新。
(5)一旦所有文件都獲取成功,它們會自動移送到真正的離線緩存中,并向 applicationCache 對象發送一個 cached 事件。鑒于文檔早已經被從緩存加載到瀏覽器中,所以更新后的文檔不會重新渲染,直到頁面重新加載(可以手動或通過程序).
以上只是一些詳細步驟,具體也有一些值得注意的細節,比如menifest文件中列出的資源url必須和menifest本身使用同樣的網絡協議,如果menifest文件使用的是http協議,則列表中https協議的文件就會被忽略。總之,每當在使用Application Cache的過程中遇到奇怪的問題時,隨時查閱W3C標準文檔。
2.離線緩存事件流
瀏覽器在解析HTML文檔的過程中,遇到HTML標記的menifest屬性時,就立即在后臺開啟一個新的進程下載需要離線緩存的資源。在下載離線緩存的過程中,會在ApplicationCache上觸發一系列事件。
離線緩存事件流
關于離線緩存中要觸發的事件,有一個很有趣的特性。從離線緩存W3C標準中,我們經常看到如下描述:'queue a post-load task to fire a simple event named (checking|noupdate|downloading)',每一個HTML文檔都有一個離線緩存事件隊列(queue),離線緩存下載過程中的事件都存放在這個隊列里,用于在文檔的onload事件觸發后執行。也就是說,所有的ApplicationCache事件都在html的onload事件觸發后才觸發。
3.使用離線緩存加速移動端網頁開發
上文提到過,Application Cache在移動端支持的很好,幾乎所有的android瀏覽器和ios瀏覽器都能很好的支持。事實上使用Application Cache加速移動端網頁訪問速度是行業類普遍采用的優化方案,在包括新浪微博和QQ瀏覽器等大型產品中都有非常廣泛的使用。但是在使用離線緩存時,我們需要留意一些問題。
(1).二次更新的問題
我們知道每次使用離線應用時,在有網絡連接的情況下,瀏覽器都會逐字節的檢查menifest文件是否有更新,而當menifest文件有更新時,就會重新下載menifest文件中列出的所有資源,資源下載成功后會觸發updateready事件。這時離線應用本身并不會立即更新,而會在下次訪問時才更新,這就是我們所說的二次更新。我們在開發web程序時,一般都是前端頁面和后端接口同步更新,但是二次更新問題會導致頁面更新不受控制,無法和后端接口同步更新,因此要做好后端接口的向前兼容,這迫使我們拋棄傳統的web開發思路而采取native開發思路來管理離線應用。我們可以通過檢測updateready事件,在新的緩存可用時通知用戶更新。
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
//緩存更新完畢
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
//切換為最新緩存
window.applicationCache.swapCache();
if (confirm('新版本已經更新完成,是否重新加載?')) {
window.location.reload();
}
}
}, false);
}, false);
(2).超出大小限制的問題
Application Cache的W3C標準中并沒有對大小限制做出詳細的描述。因此瀏覽器實現起來也是參差不齊,為了最大化的使用離線緩存,我們應該清楚自己業務的目標瀏覽器的離線緩存大小限制,使用chrome://appcache-internals/可以輕易的管理chrome瀏覽器的離線緩存。我們可以寫一個DEMO,采用二分搜索法,不斷的測試瀏覽器的Application Cache大小限制,直到觸發相應的error事件。這個鏈接可以測試Application Cache的大小限制。通過監聽Application的error事件來能夠處理超出離線緩存大小限制的情況:
window.applicationCache.addEventListener('error',function(e){
if(e.reason == 'quota'){
//超出離線緩存大小限制
}
});
離線緩存的是一套網頁加速方案,超出Application Cache的大小限制后,會對我們的應用有不同的影響,具體表現就是:
首次下載緩存時超出大小,所有資源都不會緩存,而是請求網絡,應用功能正常。
更新資源后超出大小,緩存不會更新,應用無法更新。
(3).webview中的問題
在標準的html5瀏覽器中,我們可以放心的使用Application Cache,并且不需要任何設置。但是在webview中,則可能需要顯示的設置,比如android系統的webview默認是不支持Application Cache的,因此需要顯示設置:
webView.getSettings().setAppCacheEnabled(true);? ? ? ? //默認是關閉的
webView.getSettings().setAppCacheMaxSize(1024*1024*5); //緩存大小
webView.getSettings().setAppCachePath("路徑");? ? ? ? ? //緩存路徑
總結
以上是生活随笔為你收集整理的html5 客户端数据缓存机制,深入理解HTML5离线缓存机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: eslint不报错 vue_2-2【微信
- 下一篇: java cache-control_详