轉(zhuǎn)載:H5緩存機(jī)制淺析-移動(dòng)端Web加載性能優(yōu)化【干貨】
作者:賀輝超橡类,騰訊游戲平臺(tái)與社區(qū)產(chǎn)品部 高級(jí)工程師
目錄
1 H5緩存機(jī)制介紹
2 H5緩存機(jī)制原理分析
2.1 瀏覽器緩存機(jī)制
2.2 Dom Storgage(Web Storage)存儲(chǔ)機(jī)制
2.3 Web SQL Database存儲(chǔ)機(jī)制
2.4 Application Cache(AppCache)機(jī)制
2.5 Indexed Database (IndexedDB)
2.6 File System API
3 移動(dòng)端Web加載性能(緩存)優(yōu)化
1 H5緩存機(jī)制介紹
H5砌溺,即HTML5洋幻,是新一代的HTML標(biāo)準(zhǔn)寄症,加入很多新的特性。離線存儲(chǔ)(也可稱為緩存機(jī)制)是其中一個(gè)非常重要的特性痹屹。H5引入的離線存儲(chǔ),這意味著 web 應(yīng)用可進(jìn)行緩存,并可在沒有因特網(wǎng)連接時(shí)進(jìn)行訪問仿畸。
H5應(yīng)用程序緩存為應(yīng)用帶來三個(gè)優(yōu)勢:
離線瀏覽 - 用戶可在應(yīng)用離線時(shí)使用它們
速度 - 已緩存資源加載得更快
減少服務(wù)器負(fù)載 - 瀏覽器將只從服務(wù)器下載更新過或更改過的資源。
根據(jù)標(biāo)準(zhǔn)朗和,到目前為止错沽,H5一共有6種緩存機(jī)制,有些是之前已有眶拉,有些是H5才新加入的千埃。
瀏覽器緩存機(jī)制
Dom Storgage(Web Storage)存儲(chǔ)機(jī)制
Web SQL Database存儲(chǔ)機(jī)制
Application Cache(AppCache)機(jī)制
Indexed Database (IndexedDB)
File System API
下面我們首先分析各種緩存機(jī)制的原理、用法及特點(diǎn)忆植;然后針對Anroid移動(dòng)端Web性能加載優(yōu)化的需求放可,看如果利用適當(dāng)緩存機(jī)制來提高Web的加載性能。
2 H5緩存機(jī)制原理分析
2.1 瀏覽器緩存機(jī)制
瀏覽器緩存機(jī)制是指通過HTTP協(xié)議頭里的Cache-Control(或Expires)和Last-Modified(或Etag)等字段來控制文件緩存的機(jī)制唱逢。這應(yīng)該是WEB中最早的緩存機(jī)制了吴侦,是在HTTP協(xié)議中實(shí)現(xiàn)的,有點(diǎn)不同于Dom Storage坞古、AppCache等緩存機(jī)制备韧,但本質(zhì)上是一樣的』痉悖可以理解為织堂,一個(gè)是協(xié)議層實(shí)現(xiàn)的,一個(gè)是應(yīng)用層實(shí)現(xiàn)的奶陈。
Cache-Control用于控制文件在本地緩存有效時(shí)長易阳。最常見的,比如服務(wù)器回包:Cache-Control:max-age=600表示文件在本地應(yīng)該緩存吃粒,且有效時(shí)長是600秒(從發(fā)出請求算起)潦俺。在接下來600秒內(nèi),如果有請求這個(gè)資源徐勃,瀏覽器不會(huì)發(fā)出HTTP請求事示,而是直接使用本地緩存的文件。
Last-Modified是標(biāo)識(shí)文件在服務(wù)器上的最新更新時(shí)間僻肖。下次請求時(shí)肖爵,如果文件緩存過期,瀏覽器通過If-Modified-Since字段帶上這個(gè)時(shí)間臀脏,發(fā)送給服務(wù)器劝堪,由服務(wù)器比較時(shí)間戳來判斷文件是否有修改冀自。如果沒有修改,服務(wù)器返回304告訴瀏覽器繼續(xù)使用緩存秒啦;如果有修改熬粗,則返回200,同時(shí)返回最新的文件帝蒿。
Cache-Control通常與Last-Modified一起使用荐糜。一個(gè)用于控制緩存有效時(shí)間巷怜,一個(gè)在緩存失效后葛超,向服務(wù)查詢是否有更新。
Cache-Control還有一個(gè)同功能的字段:Expires延塑。Expires的值一個(gè)絕對的時(shí)間點(diǎn)绣张,如:Expires: Thu, 10 Nov 2015 08:45:11 GMT,表示在這個(gè)時(shí)間點(diǎn)之前关带,緩存都是有效的侥涵。
Expires是HTTP1.0標(biāo)準(zhǔn)中的字段,Cache-Control是HTTP1.1標(biāo)準(zhǔn)中新加的字段宋雏,功能一樣芜飘,都是控制緩存的有效時(shí)間。當(dāng)這兩個(gè)字段同時(shí)出現(xiàn)時(shí)磨总,Cache-Control是高優(yōu)化級(jí)的嗦明。
Etag也是和Last-Modified一樣,對文件進(jìn)行標(biāo)識(shí)的字段蚪燕。不同的是娶牌,Etag的取值是一個(gè)對文件進(jìn)行標(biāo)識(shí)的特征字串。在向服務(wù)器查詢文件是否有更新時(shí)馆纳,瀏覽器通過If-None-Match字段把特征字串發(fā)送給服務(wù)器诗良,由服務(wù)器和文件最新特征字串進(jìn)行匹配,來判斷文件是否有更新鲁驶。沒有更新回包304鉴裹,有更新回包200。Etag和Last-Modified可根據(jù)需求使用一個(gè)或兩個(gè)同時(shí)使用钥弯。兩個(gè)同時(shí)使用時(shí)径荔,只要滿足基中一個(gè)條件,就認(rèn)為文件沒有更新寿羞。
另外有兩種特殊的情況:
手動(dòng)刷新頁面(F5)猖凛,瀏覽器會(huì)直接認(rèn)為緩存已經(jīng)過期(可能緩存還沒有過期),在請求中加上字段:Cache-Control:max-age=0绪穆,發(fā)包向服務(wù)器查詢是否有文件是否有更新辨泳。
強(qiáng)制刷新頁面(Ctrl+F5)虱岂,瀏覽器會(huì)直接忽略本地的緩存(有緩存也會(huì)認(rèn)為本地沒有緩存),在請求中加上字段:Cache-Control:no-cache(或Pragma:no-cache)菠红,發(fā)包向服務(wù)重新拉取文件第岖。
下面是通過Google Chrome瀏覽器(用其他瀏覽器+抓包工具也可以)自帶的開發(fā)者工具,對一個(gè)資源文件不同情況請求與回包的截圖试溯。
首次請求:200
緩存有效期內(nèi)請求:200(from cache)
緩存過期后請求:304(Not Modified)
一般瀏覽器會(huì)將緩存記錄及緩存文件存在本地Cache文件夾中蔑滓。Android下App如果使用Webview,緩存的文件記錄及文件內(nèi)容會(huì)存在當(dāng)前app的data目錄中遇绞。
分析:Cache-Control和Last-Modified一般用在Web的靜態(tài)資源文件上键袱,如JS、CSS和一些圖像文件摹闽。通過設(shè)置資源文件緩存屬性蹄咖,對提高資源文件加載速度,節(jié)省流量很有意義付鹿,特別是移動(dòng)網(wǎng)絡(luò)環(huán)境澜汤。但問題是:緩存有效時(shí)長該如何設(shè)置?如果設(shè)置太短舵匾,就起不到緩存的使用俊抵;如果設(shè)置的太長,在資源文件有更新時(shí)坐梯,瀏覽器如果有緩存徽诲,則不能及時(shí)取到最新的文件。
Last-Modified需要向服務(wù)器發(fā)起查詢請求烛缔,才能知道資源文件有沒有更新馏段。雖然服務(wù)器可能返回304告訴沒有更新,但也還有一個(gè)請求的過程践瓷。對于移動(dòng)網(wǎng)絡(luò)院喜,這個(gè)請求可能是比較耗時(shí)的。有一種說法叫“消滅304”晕翠,指的就是優(yōu)化掉304的請求喷舀。
抓包發(fā)現(xiàn),帶if-Modified-Since字段的請求淋肾,如果服務(wù)器回包304硫麻,回包帶有Cache-Control:max-age或Expires字段,文件的緩存有效時(shí)間會(huì)更新樊卓,就是文件的緩存會(huì)重新有效拿愧。304回包后如果再請求,則又直接使用緩存文件了碌尔,不再向服務(wù)器查詢文件是否更新了浇辜,除非新的緩存時(shí)間再次過期券敌。
另外,Cache-Control 與 Last-Modified 是瀏覽器內(nèi)核的機(jī)制柳洋,一般都是標(biāo)準(zhǔn)的實(shí)現(xiàn)待诅,不能更改或設(shè)置。以QQ瀏覽器的X5為例熊镣,Cache-Control 與 Last-Modified 緩存不能禁用卑雁。緩存容量是12MB,不分HOST绪囱,過期的緩存會(huì)最先被清除测蹲。如果都沒過期,應(yīng)該優(yōu)先清最早的緩存或最快到期的或文件大小最大的毕箍;過期緩存也有可能還是有效的弛房,清除緩存會(huì)導(dǎo)致資源文件的重新拉取。
還有而柑,瀏覽器,如X5荷逞,在使用緩存文件時(shí)媒咳,是沒有對緩存文件內(nèi)容進(jìn)行校驗(yàn)的,這樣緩存文件內(nèi)容被修改的可能种远。
分析發(fā)現(xiàn)涩澡,瀏覽器的緩存機(jī)制還不是非常完美的緩存機(jī)制。完美的緩存機(jī)制應(yīng)該是這樣的:
緩存文件沒更新坠敷,盡可能使用緩存妙同,不用和服務(wù)器交互;
緩存文件有更新時(shí)膝迎,第一時(shí)間能使用到新的文件粥帚;
緩存的文件要保持完整性,不使用被修改過的緩存文件限次;
緩存的容量大小要能設(shè)置或控制芒涡,緩存文件不能因?yàn)榇鎯?chǔ)空間限制或過期被清除。
以X5為例卖漫,第1费尽、2條不能同時(shí)滿足,第3羊始、4條都不能滿足旱幼。
在實(shí)際應(yīng)用中,為了解決Cache-Control緩存時(shí)長不好設(shè)置的問題突委,以及為了”消滅304“柏卤,Web前端采用的方式是:
在要緩存的資源文件名中加上版本號(hào)或文件MD5值字串叹誉,如common.d5d02a02.js,common.v1.js闷旧,同時(shí)設(shè)置Cache-Control:max-age=31536000长豁,也就是一年。在一年時(shí)間內(nèi)忙灼,資源文件如果本地有緩存匠襟,就會(huì)使用緩存;也就不會(huì)有304的回包该园。
如果資源文件有修改酸舍,則更新文件內(nèi)容,同時(shí)修改資源文件名里初,如common.v2.js啃勉,html頁面也會(huì)引用新的資源文件名。
通過這種方式双妨,實(shí)現(xiàn)了:緩存文件沒有更新淮阐,則使用緩存;緩存文件有更新刁品,則第一時(shí)間使用最新文件的目的泣特。即上面說的第1、2條挑随。第3状您、4條由于瀏覽器內(nèi)部機(jī)制,目前還無法滿足兜挨。
2.2 Dom Storage存儲(chǔ)機(jī)制
DOM存儲(chǔ)是一套在Web Applications 1.0 規(guī)范中首次引入的與存儲(chǔ)相關(guān)的特性的總稱膏孟,現(xiàn)在已經(jīng)分離出來,單獨(dú)發(fā)展成為獨(dú)立的W3C Web存儲(chǔ)規(guī)范拌汇。 DOM存儲(chǔ)被設(shè)計(jì)為用來提供一個(gè)更大存儲(chǔ)量柒桑、更安全、更便捷的存儲(chǔ)方法担猛,從而可以代替掉將一些不需要讓服務(wù)器知道的信息存儲(chǔ)到cookies里的這種傳統(tǒng)方法幕垦。
上面一段是對Dom Storage存儲(chǔ)機(jī)制的官方表述「盗看起來先改,Dom Storage機(jī)制類似Cookies,但有一些優(yōu)勢蒸走。
Dom Storage是通過存儲(chǔ)字符串的Key/Value對來提供的仇奶,并提供5MB(不同瀏覽器可能不同,分HOST)的存儲(chǔ)空間(Cookies才4KB)比驻。另外Dom Storage存儲(chǔ)的數(shù)據(jù)在本地该溯,不像Cookies岛抄,每次請求一次頁面,Cookies都會(huì)發(fā)送給服務(wù)器狈茉。
DOM Storage 分為 sessionStorage 和 localStorage夫椭。localStorage 對象和 sessionStorage 對象使用方法基本相同,它們的區(qū)別在于作用的范圍不同氯庆。sessionStorage 用來存儲(chǔ)與頁面相關(guān)的數(shù)據(jù)蹭秋,它在頁面關(guān)閉后無法使用。而 localStorage 則持久存在堤撵,在頁面關(guān)閉后也可以使用仁讨。
Dom Storage提供了以下的存儲(chǔ)接口:
sessionStorage 是個(gè)全局對象,它維護(hù)著在頁面會(huì)話(page session)期間有效的存儲(chǔ)空間实昨。只要瀏覽器開著洞豁,頁面會(huì)話周期就會(huì)一直持續(xù)。當(dāng)頁面重新載入(reload)或者被恢復(fù)(restores)時(shí)荒给,頁面會(huì)話也是一直存在的丈挟。每在新標(biāo)簽或者新窗口中打開一個(gè)新頁面,都會(huì)初始化一個(gè)新的會(huì)話锐墙。
當(dāng)瀏覽器被意外刷新的時(shí)候礁哄,一些臨時(shí)數(shù)據(jù)應(yīng)當(dāng)被保存和恢復(fù)。sessionStorage 對象在處理這種情況的時(shí)候是最有用的溪北。比如恢復(fù)我們在表單中已經(jīng)填寫的數(shù)據(jù)。
把上面的代碼復(fù)制到session_storage.html(也可以從附件中直接下載)頁面中夺脾,用Google Chrome瀏覽器(點(diǎn)擊查看支持Dom Storage的瀏覽器)的不同PAGE或WINDOW打開之拨,在輸入框中分別輸入不同的文字,再點(diǎn)擊“Save”咧叭,然后分別刷新蚀乔。每個(gè)PAGE或WINDOW顯示都是當(dāng)前PAGE輸入的內(nèi)容,互不影響菲茬。關(guān)閉PAGE吉挣,再重新打開,上一次輸入保存的內(nèi)容已經(jīng)沒有了婉弹。
Local Storage的接口睬魂、用法與Session Storage一樣,唯一不同的是:Local Storage保存的數(shù)據(jù)是持久性的镀赌。當(dāng)前PAGE 關(guān)閉(Page Session結(jié)束后)氯哮,保存的數(shù)據(jù)依然存在。重新打開PAGE商佛,上次保存的數(shù)據(jù)可以獲取到喉钢。另外姆打,Local Storage是全局性的,同時(shí)打開兩個(gè)PAGE會(huì)共享一份存數(shù)據(jù)肠虽,在一個(gè)PAGE中修改數(shù)據(jù)幔戏,另一個(gè)PAGE中是可以感知到的。
將上面代碼復(fù)制到local_storage.html的頁面中税课,用瀏覽器打開闲延,pageLoadCount的值是1;關(guān)閉PAGE重新打開伯复,pageLoadCount的值是2慨代。這是因?yàn)榈谝淮蔚闹狄呀?jīng)保存了。
用兩個(gè)PAGE同時(shí)打開local_storage.html啸如,并分別交替刷新侍匙,發(fā)現(xiàn)兩個(gè)PAGE是共享一個(gè)pageLoadCount的。
分析:Dom Storage 給Web提供了一種更錄活的數(shù)據(jù)存儲(chǔ)方式叮雳,存儲(chǔ)空間更大(相對Cookies)想暗,用法也比較簡單,方便存儲(chǔ)服務(wù)器或本地的一些臨時(shí)數(shù)據(jù)帘不。
從DomStorage提供的接口來看说莫,DomStorage適合存儲(chǔ)比較簡單的數(shù)據(jù),如果要存儲(chǔ)結(jié)構(gòu)化的數(shù)據(jù)寞焙,可能要借助JASON了储狭,將要存儲(chǔ)的對象轉(zhuǎn)為JASON字串。不太適合存儲(chǔ)比較復(fù)雜或存儲(chǔ)空間要求比較大的數(shù)據(jù)捣郊,也不適合存儲(chǔ)靜態(tài)的文件等辽狈。
在Android內(nèi)嵌Webview中,需要通過Webview設(shè)置接口啟用Dom Storage呛牲。
拿 Android類比的話刮萌,Web 的Dom Storage機(jī)制類似于Android的SharedPreference機(jī)制。
2.3 Web SQL Database存儲(chǔ)機(jī)制
H5也提供基于SQL的數(shù)據(jù)庫存儲(chǔ)機(jī)制娘扩,用于存儲(chǔ)適合數(shù)據(jù)庫的結(jié)構(gòu)化數(shù)據(jù)着茸。根據(jù)官方的標(biāo)準(zhǔn)文檔,Web SQL Database存儲(chǔ)機(jī)制不再推薦使用琐旁,將來也不再維護(hù)涮阔,而是推薦使用AppCache和IndexedDB。
現(xiàn)在主流的瀏覽器(點(diǎn)擊查看瀏覽器支持情況)都還是支持Web SQL Database存儲(chǔ)機(jī)制的旋膳。Web SQL Database存儲(chǔ)機(jī)制提供了一組API供Web App創(chuàng)建澎语、存儲(chǔ)、查詢數(shù)據(jù)庫。
下面通過簡單的例子擅羞,演示下Web SQL Database的使用尸变。
將上面代碼復(fù)制到sql_database.html中,用瀏覽器打開减俏,可看到下面的內(nèi)容召烂。
官方建議瀏覽器在實(shí)現(xiàn)時(shí),對每個(gè)HOST的數(shù)據(jù)庫存儲(chǔ)空間作一定限制娃承,建議默認(rèn)是5MB(分HOST)的配額奏夫;達(dá)到上限后,可以申請更多存儲(chǔ)空間历筝。另外酗昼,現(xiàn)在主流瀏覽器SQL Database的實(shí)現(xiàn)都是基于SQLite。
分析:SQL Database的主要優(yōu)勢在于能夠存儲(chǔ)結(jié)構(gòu)復(fù)雜的數(shù)據(jù)梳猪,能充分利用數(shù)據(jù)庫的優(yōu)勢麻削,可方便對數(shù)據(jù)進(jìn)行增加、刪除春弥、修改呛哟、查詢。由于SQL語法的復(fù)雜性匿沛,使用起來麻煩一些扫责。SQL Database也不太適合做靜態(tài)文件的緩存。
在Android內(nèi)嵌Webview中逃呼,需要通過Webview設(shè)置接口啟用SQL Database鳖孤,同時(shí)還要設(shè)置數(shù)據(jù)庫文件的存儲(chǔ)路徑。
Android系統(tǒng)也使用了大量的數(shù)據(jù)庫用來存儲(chǔ)數(shù)據(jù)抡笼,比如聯(lián)系人淌铐、短消息等;數(shù)據(jù)庫的格式也SQLite蔫缸。Android也提供了API來操作SQLite。Web SQL Database存儲(chǔ)機(jī)制就是通過提供一組API际起,借助瀏覽器的實(shí)現(xiàn)拾碌,將這種Native的功能提供給了Web App。
2.4 Application Cache機(jī)制
Application Cache(簡稱AppCache)似乎是為支持Web App離線使用而開發(fā)的緩存機(jī)制街望。它的緩存機(jī)制類似于瀏覽器的緩存(Cache-Control 和 Last-Modified)機(jī)制校翔,都是以文件為單位進(jìn)行緩存,且文件有一定更新機(jī)制灾前。但AppCache是對瀏覽器緩存機(jī)制的補(bǔ)充防症,不是替代。
先拿W3C官方的一個(gè)例子,說下AppCache機(jī)制的用法與功能蔫敲。
上面HTML文檔饲嗽,引用外部一個(gè)JS文件和一個(gè)GIF圖片文件,在其HTML頭中通過manifest屬性引用了一個(gè)appcache結(jié)尾的文件奈嘿。
我們在Google Chrome瀏覽器(點(diǎn)擊查看瀏覽器支持詳情)中打開這個(gè)HTML鏈接貌虾,JS功能正常,圖片也顯示正常裙犹。禁用網(wǎng)絡(luò)尽狠,關(guān)閉瀏覽器重新打開這個(gè)鏈接,發(fā)現(xiàn)JS工作正常叶圃,圖片也顯示正常袄膏。當(dāng)然也有可能是瀏覽緩存起的作用,我們可以在文件的瀏覽器緩存過期后掺冠,禁用網(wǎng)絡(luò)再試沉馆,發(fā)現(xiàn)HTML頁面也是正常的。
通過Google Chrome瀏覽器自帶的工具赫舒,我們可以查看已經(jīng)緩存的AppCache(分HOST)
上面截圖中的緩存悍及,就是我們剛才打開HTML的頁面AppCache。從截圖中看接癌,HTML頁面及HTML引用的JS心赶、GIF圖像文件都被緩存了;另外HTML頭中manifest屬性引用的appcache文件也緩存了缺猛。
AppCache的原理有兩個(gè)關(guān)鍵點(diǎn):manifest屬性和manifest文件缨叫。
HTML在頭中通過manifest屬性引用manifest文件。manifest文件荔燎,就是上面以appcache結(jié)尾的文件耻姥,是一個(gè)普通文件文件,列出了需要緩存的文件有咨。
上面截圖中的manifest文件琐簇,就HTML代碼引用的manifest文件。文件比較簡單座享,第一行是關(guān)鍵字婉商,第二、三行就是要緩存的文件路徑(相對路徑)渣叛。這只是最簡單的manifest文件丈秩,完整的還包括其他關(guān)鍵字與內(nèi)容。引用manifest文件的HTML和manifest文件中列出的要緩存的文件最終都會(huì)被瀏覽器緩存淳衙。
完整的manifest文件蘑秽,包括三個(gè)Section饺著,類型Windows中ini配置文件的Section,不過不要中括號(hào)肠牲。
CACHE MANIFEST - Files listed under this header will be cached after they are downloaded for the first time
NETWORK - Files listed under this header require a connection to the server, and will never be cached
FALLBACK - Files listed under this header specifies fallback pages if a page is inaccessible
完整的manifest文件幼衰,如:
總的來說,瀏覽器在首次加載HTML文件時(shí)埂材,會(huì)解析manifest屬性塑顺,并讀取manifest文件,獲取Section:CACHE MANIFEST下要緩存的文件列表俏险,再對文件緩存严拒。
AppCache的緩存文件,與瀏覽器的緩存文件分開存儲(chǔ)的竖独,還是一份裤唠?應(yīng)該是分開的。因?yàn)锳ppCache在本地也有5MB(分HOST)的空間限制莹痢。
AppCache在首次加載生成后种蘸,也有更新機(jī)制。被緩存的文件如果要更新竞膳,需要更新manifest文件航瞭。因?yàn)闉g覽器在下次加載時(shí),除了會(huì)默認(rèn)使用緩存外坦辟,還會(huì)在后臺(tái)檢查manifest文件有沒有修改(byte ? by byte)刊侯。發(fā)現(xiàn)有修改,就會(huì)重新獲取manifest文件锉走,對Section:CACHE MANIFEST下文件列表檢查更新滨彻。manifest文件與緩存文件的檢查更新也遵守瀏覽器緩存機(jī)制。
如用用戶手動(dòng)清了AppCache緩存挪蹭,下次加載時(shí)亭饵,瀏覽器會(huì)重新生成緩存,也可算是一種緩存的更新梁厉。另外辜羊, Web App也可用代碼實(shí)現(xiàn)緩存更新。
分析:AppCache看起來是一種比較好的緩存方法词顾,除了緩存靜態(tài)資源文件外只冻,也適合構(gòu)建Web離線App。在實(shí)際使用中有些需要注意的地方计技,有一些可以說是”坑“。
要更新緩存的文件山橄,需要更新包含它的manifest文件垮媒,那怕只加一個(gè)空格舍悯。常用的方法,是修改manifest文件注釋中的版本號(hào)睡雇。如:# 2012-02-21 v1.0.0
被緩存的文件萌衬,瀏覽器是先使用,再通過檢查manifest文件是否有更新來更新緩存文件它抱。這樣緩存文件可能用的不是最新的版本秕豫。
在更新緩存過程中,如果有一個(gè)文件更新失敗观蓄,則整個(gè)更新會(huì)失敗混移。
manifest和引用它的HTML要在相同HOST。
manifest文件中的文件列表侮穿,如果是相對路徑歌径,則是相對manifest文件的相對路徑怜森。
manifest也有可能更新出錯(cuò)郭膛,導(dǎo)致緩存文件更新失敗。
沒有緩存的資源在已經(jīng)緩存的HTML中不能加載跋炕,即使有網(wǎng)絡(luò)克锣。例如:http://appcache-demo.s3-website-us-east-1.amazonaws.com/without-network/
manifest文件本身不能被緩存茵肃,且manifest文件的更新使用的是瀏覽器緩存機(jī)制。所以manifest文件的Cache-Control緩存時(shí)間不能設(shè)置太長袭祟。
另外验残,根據(jù)官方文檔,AppCache已經(jīng)不推薦使用了榕酒,標(biāo)準(zhǔn)也不會(huì)再支持∨卟玻現(xiàn)在主流的瀏覽器都是還支持AppCache的,以后就不太確定了想鹰。
在Android內(nèi)嵌Webview中紊婉,需要通過Webview設(shè)置接口啟用AppCache,同時(shí)還要設(shè)置緩存文件的存儲(chǔ)路徑辑舷,另外還可以設(shè)置緩存的空間大小喻犁。
2.5 Indexed Database
IndexedDB也是一種數(shù)據(jù)庫的存儲(chǔ)機(jī)制,但不同于已經(jīng)不再支持的Web SQL Database何缓。IndexedDB不是傳統(tǒng)的關(guān)系數(shù)據(jù)庫肢础,可歸為NoSQL數(shù)據(jù)庫。IndexedDB又類似于Dom Storage的key-value的存儲(chǔ)方式碌廓,但功能更強(qiáng)大传轰,且存儲(chǔ)空間更大。
IndexedDB存儲(chǔ)數(shù)據(jù)是key-value的形式谷婆。Key是必需慨蛙,且要唯一辽聊;Key可以自己定義,也可由系統(tǒng)自動(dòng)生成期贫。Value也是必需的跟匆,但Value非常靈活,可以是任何類型的對象通砍。一般Value都是通過Key來存取的玛臂。
IndexedDB提供了一組API,可以進(jìn)行數(shù)據(jù)存封孙、取以及遍歷迹冤。這些API都是異步的,操作的結(jié)果都是在回調(diào)中返回敛瓷。
下面代碼演示了IndexedDB中DB的打開(創(chuàng)建)叁巨、存儲(chǔ)對象(可理解成有關(guān)系數(shù)據(jù)的”表“)的創(chuàng)建及數(shù)據(jù)存取、遍歷基本功能呐籽。
將上面的代碼復(fù)制到indexed_db.html中锋勺,用Google Chrome瀏覽器(點(diǎn)擊查看游戲器支持詳情)打開,就可以添加狡蝶、查詢數(shù)據(jù)庶橱。在Chrome的開發(fā)者工具中,能查看創(chuàng)建的DB贪惹、存儲(chǔ)對象(可理解成表)以及表中添加的數(shù)據(jù)苏章。
IndexedDB有個(gè)非常強(qiáng)大的功能,就是index(索引)奏瞬。它可對Value對象中任何屬性生成索引枫绅,然后可以基于索引進(jìn)行Value對象的快速查詢。
要生成索引或支持索引查詢數(shù)據(jù)硼端,需求在首次生成存儲(chǔ)對象時(shí)并淋,調(diào)用接口生成屬性的索引≌渥颍可以同時(shí)對對象的多個(gè)不同屬性創(chuàng)建索引县耽。如下面代碼就對name和email兩個(gè)屬性都生成了索引。
生成索引后镣典,就可以基于索引進(jìn)行數(shù)據(jù)的查詢兔毙。
分析:IndexedDB是一種靈活且功能強(qiáng)大的數(shù)據(jù)存儲(chǔ)機(jī)制,它集合了Dom Storage和Web SQL Database的優(yōu)點(diǎn)兄春,用于存儲(chǔ)大塊或復(fù)雜結(jié)構(gòu)的數(shù)據(jù)澎剥,提供更大的存儲(chǔ)空間,使用起來也比較簡單赶舆‰热梗可以作為Web SQL Database的替代趾唱。不太適合靜態(tài)文件的緩存。
以key-value的方式存取對象蜻懦,可以是任何類型值或?qū)ο螅ǘM(jìn)制夕晓。
可以對對象任何屬性生成索引宛乃,方便查詢。
較大的存儲(chǔ)空間蒸辆,默認(rèn)推薦250MB(分HOST)征炼,比Dom Storage的5MB要大的多。
通過數(shù)據(jù)庫的事務(wù)(tranction)機(jī)制進(jìn)行數(shù)據(jù)操作躬贡,保證數(shù)據(jù)一致性谆奥。
異步的API調(diào)用,避免造成等待而影響體驗(yàn)拂玻。
Android 在4.4開始加入對IndexedDB的支持酸些,只需打開允許JS執(zhí)行的開關(guān)就好了。
2.6 File System API
File System API是H5新加入的存儲(chǔ)機(jī)制檐蚜。它為Web App提供了一個(gè)虛擬的文件系統(tǒng)魄懂,就像Native App訪問本地文件系統(tǒng)一樣。由于安全性的考慮闯第,這個(gè)虛擬文件系統(tǒng)有一定的限制市栗。Web App在虛擬的文件系統(tǒng)中,可以進(jìn)行文件(夾)的創(chuàng)建咳短、讀填帽、寫、刪除咙好、遍歷等操作篡腌。
File System API也是一種可選的緩存機(jī)制,和前面的SQLDatabase敷扫、IndexedDB和AppCache等一樣哀蘑。File System API有自己的一些特定的優(yōu)勢:
可以滿足大塊的二進(jìn)制數(shù)據(jù)( large binary blobs)存儲(chǔ)需求。
可以通過預(yù)加載資源文件來提高性能葵第。
可以直接編輯文件绘迁。
瀏覽器給虛擬文件系統(tǒng)提供了兩種類型的存儲(chǔ)空間:臨時(shí)的和持久性的。臨時(shí)的存儲(chǔ)空間是由瀏覽器自動(dòng)分配的卒密,但可能被瀏覽器回收缀台;持久性的存儲(chǔ)空間需要顯示的申請,申請時(shí)瀏覽器會(huì)給用戶一提示哮奇,需要用戶進(jìn)行確認(rèn)膛腐。持久性的存儲(chǔ)空間是WebApp自己管理睛约,瀏覽器不會(huì)回收,也不會(huì)清除內(nèi)容哲身。持久性的存儲(chǔ)空間大小是通過配額來管理的辩涝,首次申請時(shí)會(huì)一個(gè)初始的配額,配額用完需要再次申請勘天。
虛擬的文件系統(tǒng)是運(yùn)行在沙盒中怔揩。不同WebApp的虛擬文件系統(tǒng)是互相隔離的,虛擬文件系統(tǒng)與本地文件系統(tǒng)也是互相隔離的脯丝。
File System API提供了一組文件與文件夾的操作接口商膊,有同步和異步兩個(gè)版本,可滿足不同的使用場景宠进。下面通過一個(gè)文件創(chuàng)建晕拆、讀、寫的例子材蹬,演示下簡單的功能與用法实幕。
將上面代碼復(fù)制到file_system_api.html文件中,用Google Chrome瀏覽器打開(現(xiàn)在File System API只有Chrome 43+赚导、Opera 32+以及Chrome for Android 46+ 這三個(gè)瀏覽器支持茬缩,點(diǎn)擊查看詳細(xì)支持情況)。由于Google Chrome禁用了本地HTML文件中的File System API功能吼旧,在啟動(dòng)Chrome時(shí)凰锡,要加上”—allow-file-access-from-files“命令行參數(shù)。
上面截圖圈暗,左邊是HTML運(yùn)行的結(jié)果掂为,右邊是Chrome 開發(fā)者工具中看到的Web的文件系統(tǒng)≡贝基本上H5的幾種緩存機(jī)制的數(shù)據(jù)都能在這個(gè)開發(fā)者工具看到勇哗,非常方便。
分析:File System API給Web App帶來了文件系統(tǒng)的功能寸齐,Native文件系統(tǒng)的功能在Web App中都有相應(yīng)的實(shí)現(xiàn)欲诺。任何需要通過文件來管理數(shù)據(jù),或通過文件系統(tǒng)進(jìn)行數(shù)據(jù)管理的場景都比較適合渺鹦。
到目前扰法,Android系統(tǒng)的Webview還不支持File System API。
3 移動(dòng)端Web加載性能(緩存)優(yōu)化
分析完H5提供的各種緩存機(jī)制毅厚,回到移動(dòng)端(針對Android塞颁,可能也適用于iOS)的場景。現(xiàn)在Android App(包括手Q和WX)大多嵌入了Webview的組件(系統(tǒng)Webview或QQ游覽器的X5組件),通過內(nèi)嵌Webview來加載一些H5的運(yùn)營活動(dòng)頁面或資訊頁祠锣。這樣可充分發(fā)揮Web前端的優(yōu)勢:快速開發(fā)酷窥、發(fā)布,靈活上下線伴网。但Webview也有一些不可忽視的問題蓬推,比較突出的就是加載相對較慢,會(huì)相對消耗較多流量澡腾。
通過對一些H5頁面進(jìn)行調(diào)試及抓包發(fā)現(xiàn)拳氢,每次加載一個(gè)H5頁面,都會(huì)有較多的請求蛋铆。除了HTML主URL自身的請求外,HTML外部引用的JS放接、CSS刺啦、字體文件、圖片都是一個(gè)獨(dú)立的HTTP請求纠脾,每一個(gè)請求都串行的(可能有連接復(fù)用)玛瘸。這么多請求串起來,再加上瀏覽器解析苟蹈、渲染的時(shí)間糊渊,Web整體的加載時(shí)間變得較長;請求文件越多慧脱,消耗的流量也會(huì)越多渺绒。我們可綜合使用上面說到幾種緩存機(jī)制,來幫助我們優(yōu)化Web的加載性能菱鸥。
結(jié)論:綜合各種緩存機(jī)制比較宗兼,對于靜態(tài)文件,如JS氮采、CSS殷绍、字體、圖片等鹊漠,適合通過瀏覽器緩存機(jī)制來進(jìn)行緩存主到,通過緩存文件可大幅提升Web的加載速度,且節(jié)省流量躯概。但也有一些不足:緩存文件需要首次加載后才會(huì)產(chǎn)生登钥;瀏覽器緩存的存儲(chǔ)空間有限,緩存有被清除的可能楞陷;緩存的文件沒有校驗(yàn)怔鳖。要解決這些不足,可以參考手Q的離線包,它有效的解決了這些不足结执。
對于Web在本地或服務(wù)器獲取的數(shù)據(jù)度陆,可以通過Dom Storage和IndexedDB進(jìn)行緩存。也在一定程度上減少和Server的交互献幔,提高加載速度懂傀,同時(shí)節(jié)省流量。
當(dāng)然Web的性能優(yōu)化蜡感,還包括選擇合適的圖片大小蹬蚁,避免JS和CSS造成的阻塞等。這就需要Web前端的同事根據(jù)一些規(guī)范和一些調(diào)試工具進(jìn)行優(yōu)化了郑兴。
參考資料:
瀏覽器緩存機(jī)制:
http cache筆記
http://imweb.io/topic/5623b34e34764b2c16769746
Web緩存機(jī)制系列
http://www.alloyteam.com/2012/03/web-cache-1-web-cache-overview/
Web SQL Database:
A simple TODO List Using Web SQL Database
http://www.html5rocks.com/en/tutorials/webdatabase/todo/?redirect_from_locale=zh
W3C:Web SQL Database
http://dev.w3.org/html5/webdatabase/
HTML5:Web SQL Database
http://www.tutorialspoint.com/html5/html5_web_sql.htm
Dom Storage:
淺談Html5的Dom Storage
http://www.ibm.com/developerworks/cn/web/1107_gaoly_html5storage/
Dom Storage
https://developer.mozilla.org/zh-CN/docs/Web/Guide/API/DOM/Storage
Application Cache:
Html5 Application Cache
http://www.w3schools.com/html/html5_app_cache.asp
Using the application cache
https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache
Common Pitfalls to Avoid when Using HTML5 Application Cache
http://www.sitepoint.com/common-pitfalls-avoid-using-html5-application-cache/
Application Cache is a Douchebag
http://alistapart.com/article/application-cache-is-a-douchebag
IndexedDB:
Working with IndexedDB
http://code.tutsplus.com/tutorials/working-with-indexeddb--net-34673
Working with IndexedDB -Part2
http://code.tutsplus.com/tutorials/working-with-indexeddb-part-2--net-35355
IndexedDB:瀏覽器端數(shù)據(jù)庫
http://javascript.ruanyifeng.com/bom/indexeddb.html
W3C:Indexed Database API
http://www.w3.org/TR/IndexedDB/
File System API:
Debugging the FileSystem API
https://developers.google.com/web/updates/2011/08/Debugging-the-Filesystem-API
Building an HTML5 Text Editor with the FileSystem APIs
http://blog.teamtreehouse.com/building-an-html5-text-editor-with-the-filesystem-apis
Toying with the FileSystem API
http://code.tutsplus.com/tutorials/toying-with-the-html5-file-system-api--net-24719
Exploring the FileSystem APIs
http://www.html5rocks.com/en/tutorials/file/filesystem/