瀏覽器緩衝機制(2)-應用緩衝,緩衝機制
該文章在簡書上的連結瀏覽器緩衝機制2-應用緩衝
瀏覽器緩衝機制(2)-應用緩衝
在公司項目中,一些移動版的WEB頁面恰好用到了應用緩衝,故順便寫篇文章來總結下應用緩衝方面的內容。
1.應用緩衝簡介
應用緩衝(application cache)是HTML5提供的一套緩衝機制,使得WEB應用可以離線運行。除了一些舊版本的IE外,現代瀏覽器如firefox,chrome,safari大部分都是支援HTML5標準的。使用應用緩衝主要優勢有:
- 離線瀏覽:使用者可以在離線狀態瀏覽網頁內容。
- 速度更快: 因為資料存放區在瀏覽器緩衝中,瀏覽器只會下載伺服器發生改變的資源(只有.appcache檔案狀態變化時才會重新下載.appcache檔案指定的緩衝資源),這樣可以減輕伺服器的負載。
2.應用緩衝配置
要開啟應用緩衝,需要在web頁面的html標記中加上manifest屬性,如下是我的測試頁面test.html代碼:
<html manifest="test.appcache"> <head><title>appcache</title></head> <body>test appcache<img src="/test.gif"></img></body> </html>
其中test.appcache檔案為緩衝資訊清單檔(cache manifest),緩衝的資源都是在這個資訊清單檔指定。使用了應用緩衝後,載入資源的流程是這樣的(摘自參考資料1):
1)當瀏覽器訪問一個包含manifest屬性的文檔時,如果應用緩衝不存在,則瀏覽器載入文檔,擷取該清單中需要緩衝的檔案清單,產生應用緩衝的第一個版本。
2)後續對該文檔以及資訊清單檔中列出的緩衝資源的訪問會使得瀏覽器直接從應用緩衝載入。同時,瀏覽器還會向window.applicationCache對象發送一個checking事件,在遵循經典緩衝的前提下擷取資訊清單檔,關於HTTP經典緩衝機制請參見前一篇文章。
3)如果當前緩衝資訊清單檔是副本是最新的,瀏覽器將向applicationCache對象發送一個noupdate事件,至此更新過程結束。因此,如果你在伺服器上修改了任何緩衝資源,需要同時修改資訊清單檔,這樣瀏覽器才知道你的修改,此外,也要。
4)如果緩衝資訊清單檔已經修改,則資訊清單檔中列出的緩衝資源(也包括通過applicationCache.add方法添加到緩衝中的檔案)會放到一個臨時緩衝中,對於每個加入到臨時緩衝的檔案,瀏覽器會向applicationCache發送一個progress事件。如果出現任何錯誤,瀏覽器會發送一個error事件,並暫停更新。
5)一旦所以檔案都擷取成功,它們會被自動移送到真正的離線緩衝中,並向applicationCache 對象發送一個 cached 事件。鑒於文檔早已經被從緩衝載入到瀏覽器中,所以更新後的文檔不會重新渲染,直到頁面重新載入(可以手動或通過程式).也就是說,如果你的緩衝資源更新了,緩衝資訊清單檔也更新了,第一次載入頁面的時候並不會更新文檔,只有等到頁面重新載入的時候才會更新。
為了方便測試,如果需要清除離線緩衝,chrome可以通過設定中的清除瀏覽器資料或者直接存取chrome://appcache-internals/來清除,其他瀏覽器參照參考資料1.
3.緩衝資訊清單檔
一個典型的緩衝資訊清單檔test.appcache如下:
CACHE MANIFEST# v1 - 2015-03-14 23:23# This is a comment.CACHE:test.htmlnomanifest.htmlNETWORK:*FALLBACK:/fallback fallback.html
緩衝資訊清單檔第一行必須是CACHE MANIFEST,然後可以加上注釋(以#開頭)。此外就是三個段落標題,含義如下:
| 段落標題 |
說明 |
| CACHE |
顯示記錄,下面列表是需要切換到應用緩衝的顯示資源 |
| NETWORK |
網路記錄,需要從網路訪問的白名單列表 |
| FALLBACK |
後備記錄,請求資源失敗時使用 |
一個應用緩衝至少會包含一個資源,由 URI 指定。所有資源除了上面提到的顯示記錄,網路記錄,後備記錄外,還有一個類別叫主記錄。下面一一來看一下:
1)顯示記錄
每行都是一個合法的URI與一個要緩衝的資源相關聯(本段落內不允許萬用字元)。每行的URI前後允許出現空白字元。顯示記錄是顯示指定的需要加入到應用緩衝的資源清單,比如上面樣本的test.appcache中需要顯示緩衝的檔案為test.html,nomanifest.html。注意的是,不是所有的文檔html屬性都要加manifest屬性,比如我這個列表裡面的nomanifest.html文檔就沒有manifest屬性,但是只要有包含manifest屬性的文檔被訪問後,就會自動加入到應用緩衝。
2)網路記錄
每一行都是一個合法URI,該段落可以用萬用字元,比如上面的*,指示了除了應用緩衝中之外的資源需要通過網路擷取。如果這裡不設定的話,那麼沒有在應用緩衝中的資源就無法訪問。比如我這裡如果不指定NETWORK的話,則test.gif這個圖片就無法訪問到。
3)後備記錄
每一行都是一個合法URI(與一個資源關聯),當指定的資源無法訪問時訪問後面的關聯資源。比如訪問/fallback或者它的子路徑比如/fallback/child路徑時,如果沒有對應的資源,則會訪問fallback.html.
4)主記錄
主記錄是指html標籤中包含了manifest屬性的文檔,比如下面的main.html。主記錄即便沒有在顯示記錄中列出,也會在訪問時加入到應用緩衝。如main.html作為主記錄,雖然沒有在CACHE列表中,但是在訪問的時候,同樣會被加入到應用緩衝中。
#main.html<html manifest="test.appcache"> <head><title>main</title></head> <body>main html</body></html>
4.緩衝狀態(摘自參考資料1)
UNCACHED(未緩衝):一個特殊的值,用於表明一個應用緩衝對象還沒有完全初始化。
IDLE(空閑):應用緩衝此時未處於更新過程中。
CHECKING(檢查):清單已經擷取完畢並檢查更新。
DOWNLOADING(下載中):下載資源並準備加入到緩衝中,這是由於清單變化引起的。
UPDATEREADY(更新就緒):一個新版本的應用緩衝可以使用。有一個對應的事件 updateready,當下載完畢一個更新,並且還未使用 swapCache() 方法啟用更新時,該事件觸發,而不會是 cached 事件。
OBSOLETE(廢棄):應用緩衝現在被廢棄。
可以通過下面的代碼來測試緩衝清單更新情況:
function onUpdateReady() { alert('found new version!');}window.applicationCache.addEventListener('updateready', onUpdateReady);if(window.applicationCache.status === window.applicationCache.UPDATEREADY) { onUpdateReady();}
5.總結
- 顯示記錄中的資源會被加入應用緩衝中。顯示記錄中的資來源文件不一定要在html標籤加manifest屬性,只要在列表中都會加入應用緩衝。
- 主記錄是指html標籤包含manifest屬性的文檔,即便沒有在顯示記錄的列表中,也會加入應用緩衝。
- 應用緩衝資源更新後,緩衝資訊清單檔也一定要同步更新,不然瀏覽器沒有辦法知曉緩衝資源的變化。
- NETWORK段落必須設定,否則其他資源無法訪問。
- 緩衝資訊清單檔本身不要在顯示記錄中,也不要被伺服器以任何方式緩衝。比如apache可以這樣設定緩衝資訊清單檔不被緩衝。
ExpiresByType text/cache-manifest "access plus 0 seconds"
- 如果訪問緩衝文檔時加了參數,比如/test.html?name=test這樣,那麼也會直接存取應用緩衝並加入到應用緩衝中。如下面是訪問chrome://appcache-internals/得到的記錄,可以看到各種類型的記錄:
Flags URL Size (headers and data)Fallback, http://localhost/fallback.html 295 BMaster, http://localhost/main.html 703 BExplicit, http://localhost/nomanifest.html 305 BManifest, http://localhost/test.appcache 419 BExplicit, http://localhost/test.html 732 BMaster, http://localhost/test.html?name=test 732 B
6.參考資料
使用應用緩衝(參考了大部分內容並原文摘抄不少內容,向原作者表示感謝)