起源
html5之前的網頁,都是無連接,必須聯網才能訪問,這其實也是web的特色,這其實對於PC是時代問題並不大,但到了移動互聯網時代,設備終端位置不再固定,依賴無線訊號,網路的可靠性變得降低,例如坐在火車上,過了一個隧道(15分鐘),便無法存取網站,這對於web的傷害是很大的,例如《ecmascript合集》這樣的為閱讀而生的頁面。
html5便引入了cache manifest 檔案。那什麼是cache manifest呢,接下來會講到。
什麼是Cache Manifest
首先manifest是一個後綴名為minifest的文件,在文件中定義那些需要緩存的文件,支援manifest的瀏覽器,會將按照manifest文件的規則,像檔案保存在本地,從而在沒有網路連結的情況下,也能存取頁面。
當我們第一次正確配置app cache後,當我們再次訪問應用時,瀏覽器會先檢查manifest檔是否有變動,如果有變動就會把對應的變成跟新下來,同時改變瀏覽器裡面的app cache,如果沒有變動,就會直接把app cache的資源回傳,基本流程是這樣的。
Manifest的特色
離線瀏覽: 使用者可以在離線狀態下瀏覽網站內容。
更快的速度: 因為資料儲存在本地,所以速度會更快.
減輕伺服器的負載: 瀏覽器只會下載在伺服器上改變的資源。
瀏覽器支援情況
所有主流瀏覽器均支援應用程式緩存,除了 Internet Explorer。 caniuse給的答案如下圖所示。
如何使用
html新增了一個manifest屬性,可以用來指定目前頁面的manifest檔。
建立一個和html同名的manifest文件,例如頁面為index.html,那麼可以建造一個index.manifest的文件,然後給index.html的html標籤添加如下屬性即可:
Manifest檔
接下來詳細說說manifest的細節,一個典型的manifest檔案程式碼結構像下面這樣:
CACHE MANIFEST#version 1.3CACHE: test.cssNETWORK:*
manifest文件,基本格式為三段: CACHE, NETWORK,與 FALLBACK,其中NETWORK和FALLBACK為可選選項。
而第一行CACHE MANIFEST為固定格式,必須寫在前面。
以#號開頭的是註釋,通常會在第二行寫個版本號,用來在快取的檔案更新時,更改manifest的作用,可以是版本號,時間戳或md5碼等等。
CACHE:(必須)
識別出哪些檔案需要緩存,可以是相對路徑也可以是絕對路徑。
a.csshttp://yanhaijing.com/a.css
NETWORK:(可選)
這一部分是要繞過快取直接讀取的文件,可以使用通配符*。
下面的程式碼 “login.asp” 永遠不會被緩存,而且離線時是不可用的:
NETWORK:login.asp
可以使用星號來指示所有其他資源/檔案都需要因特網連線:
NETWORK:* ###FALLBACK:(可選)
指定了一個後備頁面,當資源無法存取時,瀏覽器會使用該頁面。該段落的每筆記錄都列出兩個 URI—第一個表示資源,第二個表示後備頁面。兩個 URI 都必須使用相對路徑並且與清單檔案同源。可以使用通配符。
下面的範例中,如果無法建立因特網連接,則以 “404.html” 取代 /html5/ 目錄中的所有檔案。
FALLBACK:/html5/ /404.html
下面的範例中,則以 “404.html” 取代所有檔案。
FALLBACK:*.html /404.html
如何更新快取
以下三種方式,可以更新快取:
(1)更新manifest檔
(2)透過javascript操作
(3)清除瀏覽器快取
為manifest新增或刪除文件,都可更新緩存,如果我們更改了js,而沒有新增或刪除,前面例子中註釋中的版本號,可以很好的用來更新manifest文件。
html5中引入了js操作離線快取的方法,下面的js可以手動更新本地快取。
window.applicationCache.update();
如果使用者清除了瀏覽器快取(手動或使用其他一些工具)都會重新下載檔案。
注意事項
瀏覽器對快取資料的容量限制可能不太一樣(某些瀏覽器設定的限制是每個網站 5MB)。
如果manifest文件,或是內部列舉的某一個文件無法正常下載,整個更新過程都會失敗,瀏覽器繼續全部使用舊的快取。
引用manifest的html必須與manifest檔同源,在同一個域下。
FALLBACK中的資源必須和manifest檔同源。
當一個資源被快取後,該瀏覽器直接請求這個絕對路徑也會存取快取中的資源。
網站中的其他頁面即使沒有設定manifest屬性,請求的資源如果在快取中也從快取中存取。
當manifest檔案改變時,資源請求本身也會觸發更新。
自動化工具
manifest檔案中的cache部分不能使用通配符,必須手動指定,這實在太讓人不可理解,文件一多,就成了體力活了,這裡介紹的grunt-manifest能自動產生manifest檔的目的。 grunt-manifest依賴grunt,grunt是一個自動化建置工具,如果你不知道grunt,請移動這裡。
如下的指令可以安裝grunt-manifest,並加入到依賴檔案。
grunt.initConfig({
manifest: {
generate: {
options: {
basePath: "../",
cache: ["js/app.js" , "css/style.css"]
network: ["http://*", "https://*"],
fallback: ["/ /offline.html"],
exclude: ["js/jquery.min.js"],
preferOnline: true,
verbose: true,
timestamp: true
},
"some_ /*.html",
"js/*.min.js",
"css/*.css"
],
dest: "index.manifest"
}
}
});
其中options定義產生manifest的一些自訂參數,src是要產生的文件,dest是輸出檔。
basePath 設定出入檔案的根目錄
cache 手動新增快取檔案
network 手動新增網路檔案
fallback 手動新增後備檔案
exclude 設定不加入cache的檔案
verbose 是否新增版權資訊
timestamp是否加入時間戳記
範例
要使用manifest緩存,我們首先需要寫一個manifest檔。這個文件有嚴格的格式要求,下面是個例子CACHE MANIFEST
這個頁面就使用了上面寫的manifest文件,我們用Chrome打開這個頁面就可以在控制台中找到這個manifest的工作資訊。
從這個資訊可以看出,我們設定的需要快取的兩個檔案都快取了。而且引用manifest的那個頁面也被快取了。這個很重要,這個是manifest的機制,它除了會快取設定好的檔案之外,還會快取目前引用manifest檔案的頁面(想關都關不掉)。所以使用起來很不方便,這就需要注意。
另外,manifest快取之後的東西只有在manifest檔案發生變化時才會跟新(看起來像是這個檔案的md5發生變化時才更新)。而被快取檔案更新時瀏覽器是不會去取得新檔案的。也就是說,剛剛那個頁面已經快取了test.css,現在我修改了test.css,頁面不會有任何變化。除非我修改manifest檔案本身的內容(注意是內容,不是修改時間)。一般為了更新這個緩存,可以在裡面的註解中放入修改時間來更新它。這個我就不截圖了,好麻煩的。
說完這些問題,現在回過頭來看看manifest本身的寫法。除了上面的“CACHE:”之外,還有幾個操作類型。以下是這些操作類型和說明
CACHE:設定後面的檔案為快取
NETWORK:置後面的檔案為不快取(無法設定自身頁)
置時候使用另一個檔案
SETTINGS:可以設定fast或prefer-online兩種模式
CACHE是設定緩存,之前已經說過了。
NETWORK是設定不緩存。由於manifest的機制是把整個頁面(或說Web應用)儲存的本地。所以,目前頁面使用的所有資源都必須有一個設定。如果不設定就會在頁面快取之後找不到,所以通常需要使用NETWORK來匹配所有不需要快取的資源,如下面這樣。
Since x.css does not exist, test.css is used to replace it when caching.
SETTINGS can be set to two modes, the default is fast. But in my test, I didn’t feel any difference between the two modes, so I won’t talk about it for now.
These are the most basic things about manifest cache. Another big problem is Firefox’s warning. When using manifest, a warning will appear under Firefox.
This is the most annoying part of this thing, so let’s understand it a little bit now without going into in-depth research. Let’s look back at this product after these problems are solved. In fact, the role of manifest is to localize web applications. If you just do "web application localization", it can indeed be used. But this thing is really weak in other aspects. Therefore, current projects will not consider using this painful thing. The above are just entry-level tests, and there are still many things that need to be tested. However, since it is not used now, I will not study it for the time being.