H5筆記3-資源緩存

問題描述:

在開發h5的webapp時,會需要考慮app的頁面加載性能流量節省離線緩存等問題。解決這類問題的一種方法可以考慮appcache技術,它可以將一些靜態資源緩存到客戶端本地,這樣同一個資源不用反覆的從服務器請求並下載到本地了,既可以提高頁面的加載性能,也能節省一些流量。

如何使用appcache技術?

appcache緩存技術主要通過配置文件實現。自定義一個appcache結尾的配置文件,配置需要緩存的資源,然後將這個配置文件引入到需要使用緩存的前臺頁面就行了。

1.自定義配置文件


定義一個配置文件,文件名稱自己隨便命名,但是結尾格式爲appcache。
這個就是緩存配置文件。文件配置信息如下:

CACHE MANIFEST
#v2.0.0(更新客戶端緩存文件的話,修改版本號就行了)

#需要緩存的文件列表;系統級別的,不經常變的文件可以放在這裏;
CACHE:
../../../static/bootstrap/css/bootstrap.min.css
../../../static/bootstrap/css/bootstrap-theme.min.css
../../../static/jquery/jquery.min.js
../../../static/css/model.css
../../../static/css/style.css
../../../static/HBuilder/css/mui.min.css
../../../static/HBuilder/js/mui.min.js
../../../static/js/comm.js
../../../static/android/android-require-min-v2.1.11.js
../../../static/android/android-v0.0.1.js
../../../static/js/ajaxSetup.js
../../../static/img/index_bg.png
../../../static/HBuilder/fonts/mui.ttf


#不需要緩存的文件列表;與模塊相關的動態腳本文件等放在這裏;
NETWORK:  
*

#代替方案;找不到的資源可以用其他的資源代替
FALLBACK:

注意:
文件第一行必須是CACHE MANIFEST關鍵字,些其他的信息的話,緩存會不好用;
相對路徑是相對這個緩存配置文件而言的,並不是相對前臺頁面;

2.引用配置文件


將配置文件通過manifest屬性引入到前臺頁面的html元素裏:

<!DOCTYPE html>
<html manifest="../zsfy/login/cache/beforeLogin.appcache">
  <head>
    <meta charset="utf-8" />
    <title>登錄引導頁</title>

瀏覽器訪問這個頁面,用f12查看調試頁面的resources選項,緩存信息如下:
這裏寫圖片描述

緩存成功的話,控制檯信息如下:
這裏寫圖片描述

可以看到總共緩存了14個文件。

當再次訪問這個頁面時,瀏覽器就會直接從緩存裏拿資源文件了:
這裏寫圖片描述

這裏寫圖片描述

緩存加載過程如圖:
這裏寫圖片描述

注意:
(1) manifest的加載是晚於頁面其他資源的。瀏覽器先加載引用的資源(從服務器或緩存中拿),再通過檢查 manifest 文件是否有更新來更新緩存文件。這樣緩存文件可能用的不是最新的版本。這個是比較坑的。。。

(2)不同的html頁面,配置不同的manifest文件,他們的緩存空間是單獨分開的,緩存的資源之間相互獨立。驗證這個結論的方法:
★ 定義一個manifest文件,配置緩存資源test.js文件;
★ a.html頁面和b.html頁面配置manifest文件;
★ 瀏覽器訪問a.html頁面,用F12查看test.js裏面的內容;
★ 更改服務器裏的test.js文件內容,瀏覽器訪問b.html頁面,用F12查看test.js裏面的內容爲更改後的內容;
★ 瀏覽器訪問a.html頁面,用F12查看test.js裏面的內容;反覆刷新頁面,發現還是更改之前的內容;
可見,不同頁面的緩存空間是獨立的。但是整個網站的緩存上限通常是5M.

(3)不同的html頁面,配置同一個manifest文件,他們的緩存空間是共享的。比如a,b兩個頁面引用同一份manifest A. 則更新A,更新R,刷新b, b對應的R資源更新後,a的R資源副本也會隨之更新. 這就是cache group的機制。a和b對應的application cache,同屬於同一個application cache group

(4)如果manifest文件或者是其中指定的某個資源下載失敗的話,整個cache的更新都會失敗。在這種情況下,瀏覽器將會使用老的application cache。

如何更新緩存?

有緩存必然涉及到緩存的更新,更新緩存的方法如下:

(1)更改manifest文件
每當manifest文件有更改,哪怕是加了一個空格,瀏覽器會重新下載資源文件進行緩存。通常做法是通過修改註釋信息裏的版本號來實現文件的更改。

(2)手動清除瀏覽器歷史記錄
如用用戶手動清了瀏覽器緩存,下次加載時,瀏覽器會重新生成緩存,也可算是一種緩存的更新。

(3)js腳本更新緩存
在程序中,你可以通過window.applicationCache 對象來訪問瀏覽器的app cache。你可以查看 status 屬性來獲取cache的當前狀態:

var appCache = window.applicationCache;

switch (appCache.status) {

  case appCache.UNCACHED: // UNCACHED == 0

    return ‘UNCACHED’;

    break;

  case appCache.IDLE: // IDLE == 1

    return ‘IDLE’;

    break;

  case appCache.CHECKING: // CHECKING == 2

    return ‘CHECKING’;

    break;

  case appCache.DOWNLOADING: // DOWNLOADING == 3

    return ‘DOWNLOADING’;

    break;

  case appCache.UPDATEREADY:  // UPDATEREADY == 4

    return ‘UPDATEREADY’;

    break;

  case appCache.OBSOLETE: // OBSOLETE == 5

    return ‘OBSOLETE’;

    break;

  default:

    return ‘UKNOWN CACHE STATUS’;

    break;

};

爲了通過編程更新cache,首先調用 applicationCache.update()。這將會試圖更新用戶的 cache(要求manifest文件已經改變)。最後,當 applicationCache.status 處於 UPDATEREADY 狀態時, 調用applicationCache.swapCache(),舊的cache就會被置換成新的。

var appCache = window.applicationCache;

appCache.update(); // Attempt to update the user’s cache.

…

if (appCache.status == window.applicationCache.UPDATEREADY) {

  appCache.swapCache();  // The fetch was successful, swap in the new cache.

}

像這樣使用 update()和swapCache()並不會將更新後的資源 呈現給用戶。這僅僅是讓瀏覽器檢查manifest文件是否發生了更新,然後下載指定的更新內容,重新填充app cache。因此,要讓用戶看到更新後的內容,需要兩次頁面下載,一次是更新app cache,一次是更新頁面內容。

好消息是,你可以避免兩次頁面下載帶來的麻煩。爲了讓用戶能看到你的站點的最新版本,設置一個監聽器來監聽頁面加載時的updateready 事件。

// Check if a new cache is available on page load.

window.addEventListener(‘load’, function(e) {

  window.applicationCache.addEventListener(‘updateready’, function(e) {

    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {

      // Browser downloaded a new app cache.

      // Swap it in and reload the page to get the new hotness.

      window.applicationCache.swapCache();

      if (confirm(‘A new version of this site is available. Load it?’)) {

        window.location.reload();//重點在這裏!!!!

      }

    } else {

      // Manifest didn’t changed. Nothing new to server.

    }

  }, false);

}, false);

appcache知識點總結

(1)備用資源FALLBACK列表裏的資源,必須與當前的manifest同源;備用資源也會被緩存.
(2)備用名稱空間 和 白名單名稱空間 都可以使用前綴匹配模式。即支持通配符匹配模式。可以放心的是 //www.a.com/abc 是不匹配 //www.a.com/ab的,因爲//www.a.com/ab 實際上是//www.a.com/ab/
(3)前綴匹配對端口的匹配是寬鬆的.如abc.com:80/a.png 就會被 abc.com/所匹配.
(4)window. applicationCache.update(), 只會立刻檢測manifest文件,而不會更新相應資源;
(5)一組不同的頁面引入同一個manifest文件時,這組頁面構成一個group.並已document作爲標識,來區分他們。其中任何一個的manifest或資源更新,甚至是檢測都會觸發其他頁面的applicationCache的相應事件.
(6)a,b兩個頁面引入相同資源,但a有使用manifest而b沒有。那麼即使a頁面緩存了資源,這個緩存對b頁面也不會有效。
(7)爲manifest文件配置304相關頭域時,也配置expires和cache-control : max-age。因爲chrome,safari,以及android,如果沒有expires 或 max-age時,是不會有304的,而只會是200。opera則無視一切http cache頭域.總是200。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章