杜燕忍,葛華勇,王 龍
(東華大學(xué) 信息科學(xué)與技術(shù)學(xué)院,上海 201620)
?
基于Lizard框架Ctrip Wireless H5數(shù)據(jù)存儲方式的優(yōu)化
杜燕忍,葛華勇,王龍
(東華大學(xué) 信息科學(xué)與技術(shù)學(xué)院,上海 201620)
Lizard是針對目前前端開源框架中存在的不足,由攜程研發(fā)出的適用于無線移動端開發(fā)的框架。Lizard Web App是運行在瀏覽器上的單頁應(yīng)用,所有加載資源都放在一個html文件上,所有的用戶交互都交給JavaScript,所有的通信都交給Ajax。該文基于Lizard框架實現(xiàn)Hybrid App(混合模式移動應(yīng)用)的開發(fā),并針對框架中本地存儲方式進行改進,由此提出了擴展store的存儲方式。以多態(tài)方式封裝store,由LocalStorage、IndexDB、SQLite by App替換cookie,進而支持多種本地存儲方式,該文只是針對其中一種方式即LocalStorage進行封裝,以提高攜程業(yè)務(wù)開發(fā)效率。
Lizard;Hybrid App;JavaScript;Web App;HTML;Ajax;數(shù)據(jù)存儲方式;無線移動端開發(fā)
引用格式:杜燕忍,葛華勇,王龍. 基于Lizard框架Ctrip Wireless H5數(shù)據(jù)存儲方式的優(yōu)化[J].微型機與應(yīng)用,2016,35(11):14-17,21.
近年來國內(nèi)外對Native App取得了很多重要的研究成果,但是對Hybrid App研究還比較少?;旌夏J揭苿討?yīng)用(Hybrid App)是指介于Web App與Native App這兩者之間的App[1],它雖然看上去是一個Native App,但只有一個UI WebView,里面訪問的是一個Web App,它具有Native App良好用戶交互體驗的優(yōu)勢和Web App[2]跨平臺開發(fā)的優(yōu)勢。
隨著HTML5[3-4]可通過手機瀏覽器運行,而不直接依賴于手機操作系統(tǒng),并且現(xiàn)在各大手機瀏覽器均支持HTML5[5];Mobile phone中框架的發(fā)展(例如PhoneGap)也為Web App的發(fā)展提供了契機。主流的Hybrid方案分成三種:以PhoneGap[6]為代表,以WebView作為用戶界面層,以Javascript[7-8]作為基本邏輯,與中間件通信,再由中間件訪問底層API的方式進行應(yīng)用開發(fā);以Titanium為代表,通過對開發(fā)者提供友好的開發(fā)工具,并折中地把這種開發(fā)語言轉(zhuǎn)換成原生語言,最終打包出整個應(yīng)用;以Three20為代表,在開發(fā)原生應(yīng)用的基礎(chǔ)上,嵌入WebView,但是整體的架構(gòu)使用原生應(yīng)用提供。在攜程無線[9]的Hybrid框架中,一開始就選擇了PhoneGap方案,未來攜程App會成為一個平臺。
本文基于Lizard框架[10]實現(xiàn)Hybrid App的開發(fā),針對原有框架中的本地存儲方式和第三方框架的引用進行改進和優(yōu)化,并對改進的方法進行實際項目開發(fā),結(jié)果與改進之前的結(jié)果一樣符合開發(fā)項目的要求,驗證了本方法的有效性。
H5整體架構(gòu)圖如圖1所示。由整體框架可知,無線H5基礎(chǔ)框架主要包含以下部分,各業(yè)務(wù)模塊需按要求對以下部分進行統(tǒng)一引用。
圖1 H5整體框架
(1)第三方框架:zepto、backbone、require、understore等需要統(tǒng)一引用。
(2)核心框架:Common.js,提供最基礎(chǔ)的UI、網(wǎng)絡(luò)通信(ajax)、數(shù)據(jù)存儲(cookie)等基類,以及UI組件、Widget組件、Hybrid-API等組件,需要統(tǒng)一引用。
(3)H5公共基礎(chǔ)樣式:Main.css,提供最基礎(chǔ)和公共樣式,需要統(tǒng)一引用。
(4)H5公共業(yè)務(wù)組件:各類通用的業(yè)務(wù)組件,比如常旅客、常用地址,需要統(tǒng)一引用。
(5)H5公共業(yè)務(wù)模塊攜程(登錄/注冊)、支付等業(yè)務(wù)模塊,需要統(tǒng)一引用。
2.1框架簡介
Lizard框架架構(gòu)如圖2所示,Ctrip.H5.Lizard主要由4個模塊構(gòu)成:第三方框架、核心框架、公共組件庫、業(yè)務(wù)組件庫。
(1)第三方框架:Ctrip.H5.Lizard底層依賴的第三方庫有4個:Zepto、underscore、backbone和Fastclick。
在Mobile端,Ctrip.H5.Lizard會加載Zepto,在PC端考慮到兼容性的問題,IE內(nèi)核瀏覽器會采用Jquery,Ctrip.H5.Lizard可以做到對環(huán)境自適應(yīng)進行加載。
Backbone在Ctrip.H5.Lizard是被定制的,其MVC框架中的Model和Controller的內(nèi)容根據(jù)Ctrip.H5.Lizard適用的環(huán)境被復(fù)寫。
Ctrip.H5.Lizard抽取了Fastclick的核心代碼,復(fù)寫了移動端的click事件。
(2)核心框架:Ctrip.H5.Lizard實現(xiàn)了Web App的基礎(chǔ)功能。
在Javascript[11-14]中實現(xiàn)了面向?qū)ο缶幊?OOP)的基礎(chǔ),封裝了Ajax請求,處理了本地環(huán)境下的跨域訪問,并對請求做了緩存處理,通過監(jiān)控Hash的變化,實現(xiàn)View的無縫切換。
(3)公共組件庫:Ctrip.H5.Lizard的公共組件庫涵蓋了UI組件庫和Widget組件庫兩個模塊組。
UI組件庫以特定的樣式表為基礎(chǔ),定制Ctrip Mobile的UI組件,實現(xiàn)了各種交互-電話、時間選取等,Widget組件庫提供了功能性組件庫和UI業(yè)務(wù)組件庫。
(4)業(yè)務(wù)組件庫:Ctrip.H5.Lizard的業(yè)務(wù)組件庫主要包括攜程(登錄/注冊)、支付等業(yè)務(wù)。
2.2Lizard算法流程
Lizard算法流程圖如圖3所示,Lizard渲染數(shù)據(jù)共分成5個階段:T1~T5。T1:頁面響應(yīng)時間。此時,用戶通過瀏覽器發(fā)起一個請求,當(dāng)前VIEW的HTML文件返回index.html給瀏覽器,瀏覽器接收到index.html開始解析,之后瀏覽器請求核心框架JS處理。Lizard.js收到請求,此時進入T2階段,即數(shù)據(jù)通信請求階段。Lizard.js返回核心框架中的JS文件給瀏覽器,瀏覽器收到核心框架中JS傳來的數(shù)據(jù),開始解析Model Config,根據(jù)Config中的API請求SOA數(shù)據(jù),SOA收到瀏覽器的數(shù)據(jù)請求,此時進入T3階段,即數(shù)據(jù)通信接收階段。SOA返回數(shù)據(jù)給瀏覽器,瀏覽器接收到SOA的數(shù)據(jù),此時T3階段完成,T4階段開始,瀏覽器根據(jù)接收到的SOA數(shù)據(jù),開始解析Template,此時DOM生成,但是其為隱藏狀態(tài),此時瀏覽器繼續(xù)發(fā)送請求給核心JS框架,T4階段完成。此階段又可以稱作DOM穩(wěn)定階段。JS中的核心框架收到瀏覽器的頁面邏輯請求開始進行處理,此時進入T5階段,即頁面顯示階段。JS返回處理的結(jié)果給瀏覽器,瀏覽器收到結(jié)果顯示DOM,展示頁面,T5階段完成。其中T1~T4又稱作DOM準備階段,T2~T3稱為通信準備階段,整個T1~T5又叫做Onload階段。Onload是Lizard渲染頁面階段中的View生命周期的一部分。
首先,View的生命周期與攜程無線Hybrid密不可分,在一個Hybrid架構(gòu)的頁面會有兩部分組成:Head和Content。Head是由App提供的Android/IOS原生組件,對應(yīng)IOS-NavigationBar/Android-ActionBar。Content由App提供的WebView加載H5提供的頁面,H5與App約定將一組API綁定在WebView的Window對象中。App通過IOS/Android原生方法調(diào)用到Window對象,執(zhí)行js的方法,這稱之為App Native調(diào)用Web。App實現(xiàn)對WebView URL的觀察者模式,H5通過改變URL的哈希值,App會通過解析哈希值的變化執(zhí)行對應(yīng)的操作,這稱之為Web調(diào)用App Native。Lizard支持Hybrid模式,而Lizard在對Hybrid的設(shè)計中,采用了切面編程的思想。Web與Hybrid最后的產(chǎn)品差異就在于入口文件,在入口文件中,會去做初始化,判斷當(dāng)前的環(huán)境,然后以當(dāng)前環(huán)境作為參數(shù),配置相應(yīng)的設(shè)置,切換各種服務(wù)在不同環(huán)境下的配置。所以從開發(fā)者的角度來說,不用關(guān)心當(dāng)前的環(huán)境是Web還是App,只需要調(diào)用相應(yīng)的服務(wù)即可,剩下的事情交給Lizard自身就可以。
圖2 Lizard框架架構(gòu)
圖3 Lizard算法架構(gòu)
其次,Lizard中頁面的整體布局代碼如下:
define(['libs', 'cBasePageView'], function (libs, BasePageView){
var viewhtml = '';
var View = BasePageView.extend({
onCreate: function () {
this.MYMel.html(viewhtml);
}
onLoad: function () {
this.turning();
}
onShow: function () {
}
onHide: function () {
}
});
return View;
});
在該代碼中顯示了View的4個生命周期回調(diào)順序。
onCreate -> onLoad -> onShow -> onHide
(1)onCreate
onCreate是只有在view生成時才會調(diào)用的回調(diào)。在這個回調(diào)中,一般處理View的模板構(gòu)建、初始化數(shù)據(jù)設(shè)置。onCreate只會在初始化時候執(zhí)行一次,第二次訪問不會執(zhí)行。
(2)onLoad
onCreate每次調(diào)用View時都會首先調(diào)用的回調(diào)方法。在該回調(diào)中需要處理數(shù)據(jù)請求、View的數(shù)據(jù)綁定、渲染和View的交互邏輯設(shè)置。onLoad的回調(diào)中需要執(zhí)行this.turning()才會宣告view的加載完成,進入到下一個生命周期onShow,onLoad在每次切換View時都會執(zhí)行,一般在onload中進行Ajax異步數(shù)據(jù)請求,請求suceess后調(diào)用turning方法從而觸發(fā)onShow事件。
(3)onShow
onShow是新DOM完成渲染之后進入頁面的回調(diào),部分依賴頁面渲染之后的業(yè)務(wù)邏輯可以綁定在這個回調(diào)中,onShow的執(zhí)行時機為調(diào)用turning之后,不調(diào)用turning不會執(zhí)行onShow。
(4)onHide
當(dāng)頁面執(zhí)行了從A頁面跳轉(zhuǎn)到B頁面時,A頁面會執(zhí)行hide方法,將View A推到后臺。onHide就是在A推到后臺之后的回調(diào)。
在一個應(yīng)用中數(shù)據(jù)的存儲是非常重要的功能,在攜程的應(yīng)用場景中,大量基礎(chǔ)數(shù)據(jù)會被緩存下來,比如城市列表、用戶使用歷史等信息。在Web 2.0時代,Web存儲呈現(xiàn)多樣化的趨勢,除了傳統(tǒng)的cookie,HTML5提供了LocalStorage、SessionStorage、ApplicationCache等存儲方案,同時Chrome還支持IndexDB。cookie操作在前端開發(fā)過程中經(jīng)常遇到,當(dāng)然如果只是用來存儲一些簡單的用戶數(shù)據(jù),還是比較容易的,要做的可能只是設(shè)置cookie名、值、過期時間等,讀取也只要根據(jù)cookie的名讀取相應(yīng)的cookie值即可。HTML5本地存儲的前身就是cookie,HTML5的本地存儲是使用LocalStorage對象將Web數(shù)據(jù)持久化在本地。相比較而言,HTML5本地存儲中每個域的存儲大小默認是5 MB,比起cookie的4 KB要大得多。因此,HTML5本地存儲可以看做是加強版的cookie,不受數(shù)據(jù)大小限制,有更好的彈性以及架構(gòu),可以將數(shù)據(jù)寫入到本機的ROM中,還可以在關(guān)閉瀏覽器之后再次打開時恢復(fù)數(shù)據(jù),以減少網(wǎng)絡(luò)流量。同時,這個功能算得上是另一個方向的后臺“操作記錄”,而不占用任何后臺資源,減輕硬件設(shè)備壓力,增強運行流暢性,而且存儲和讀取數(shù)據(jù)的代碼極為簡練。因此在Lizard框架中采用了LocalStorage作為解決方案。同時參考redis在本地實現(xiàn)了小型的文檔型數(shù)據(jù)庫。
在store中針對LocalStorage封裝了常用的方法,比如get(tag,oldFlag)獲取已存儲數(shù)據(jù)、getAttr(attrName,tag)獲取已存儲對象的屬性、set(value,tag,{oldVal})向store中添加數(shù)據(jù)、setAttr(attrName, attrVal,tag)設(shè)置屬性值、remove()移除數(shù)據(jù)存儲、removeAttr(attrName)移除指定對象的存儲屬性、setExpireTime(time)設(shè)置過期時間、setLifeTime(lifeTime,override)設(shè)置當(dāng)前對象的過期時間。
數(shù)據(jù)存儲的整個過程如下:
(1)創(chuàng)建storage項目。
(2)cStore模塊的引用:Lizard用cStore模塊封裝了LocalStorage的CURD操作,所以在使用數(shù)據(jù)存儲時,需要引入cStore模塊。Lizard采用require.js作為模塊加載器,所以在使用時需要顯示申明依賴關(guān)系。引用代碼如下:
(3)Store的繼承:Lizard實現(xiàn)了Javascript的OOP開發(fā),為代碼的復(fù)用提供了更好的機制。在Store的一般使用中,推薦將具體的Store繼承于cStore模塊,代碼如下:
var StoreCase = new Base.Class(Store, {
__propertys__: function () {
//設(shè)置在LocalStorage中的key值
//D代表天,H代表小時,M代表分鐘,S代表秒
}
initialize: function (MYMsuper, options) {
MYMsuper(options);
}
});
Store采用單例模式,所以需要通過StoreCase.getInstance()獲得,即var storeinstance = StoreCase.getInstance()。
(4)Store的增刪改讀:首先設(shè)置view模板,其次進行綁定操作。Store提供了3個接口做綁定操作:讀取Store.read(tag),設(shè)置/更新Store.set({...}),刪除Store.remove()。
(5)設(shè)置數(shù)據(jù)的過期時間:對于過期時間的處理,在內(nèi)部實現(xiàn)中參考redis的數(shù)據(jù)結(jié)構(gòu),本文設(shè)置了數(shù)據(jù)的過期時間。在LocalStorage中數(shù)據(jù)結(jié)構(gòu)如下:
"value":{
"inputvalue":"asdfaf"
}
"oldvalue":{
}
"timeout":"2015/12/19 15:38:37",
"savedate":"2015/12/19 15:08:37"
通過對LocalStorage的封裝,可以直接在開發(fā)時通過Lizard調(diào)用,使開發(fā)效率更快。
基于Lizard框架的無線開發(fā),是針對前端開發(fā)人員常用的一些方法、功能、組件等進行的一系列封裝,提高了開發(fā)人員的工作效率。本文首先對Lizard框架的架構(gòu)以及工作原理進行簡單闡述,并針對Lizard框架中本地存儲方式進行了優(yōu)化,在store中封裝了對LocalStorage的讀寫,實現(xiàn)了在Web上的本地緩存。其次,通過對LocalStorage的封裝,cookie與store中的LocalStorage兩種本地存儲方式可以同時使用,更加方便。最后,正如文中所提到的一樣,存儲方式還有很多,諸如IndexDB、SQLite by App等都是以后技術(shù)發(fā)展的需要。
[1] 萬曉鳳,雷繼棠,易其軍,等.基于Android智能手機平臺的AMT監(jiān)測系統(tǒng)的設(shè)計[J].電子技術(shù)應(yīng)用,2014,40(3):68-70.
[2] 朱華.AJAX在WEB開發(fā)中的應(yīng)用研究[D].哈爾濱:哈爾濱工程大學(xué),2009.
[3] 陶國榮.HTML5實戰(zhàn)[M].北京:機械工業(yè)出版社,2012.
[4] cyRotel.WEB APP,HYBRID APP與NATIVE APP的設(shè)計差異[DB/OL].(2013-2-19)[2015-08-25].http://www.uisdc.com/web-hybrid-native-app,2014-12-02.
[5] 劉艷平,俞海英.基于HTML5的Application Cache技術(shù)研究[J].微型機與應(yīng)用,2015, 34 (20):64-66.
[6] PhoneGap.API介紹[EB/OL]. (2000-01-18)[2016-01-05].http://www.phonegapcn.com/docs/zh/cn/.
[7] NICHOLAS.JavaScript高級程序設(shè)計[M].北京:人民郵電出版社,2006.
[8] 徐浩,周德華,廠卓,等.面向多終端適配的移動中間件的設(shè)計與實現(xiàn)[J].計算機科學(xué)現(xiàn)代化,2011(9):65-68.
[9] 劉妍.無線產(chǎn)品部的無線技術(shù)標(biāo)準及指南[DB/OL].(2014-12-08)[2016-01-05].http://conf.ctripcorp.com/display/Wireless/3.HTML5.
[10] 劉妍.Lizard框架[DB/OL].(2014-12-19) [2015-04-15]. http://svn.ui.sh.ctripcorp.com/lizard/2.1/doc/index.html,2014-1-25.
[11] FLANAGAN D. JavaScript權(quán)威指南[M].李強,譯.北京:機械工業(yè)出版社,2007.
[12] KEITH J. JavaScript DOM 編程藝術(shù)[M].楊濤,王建橋,楊曉去,等,譯.北京:人民郵電出版社,2006.
[13] POWERS S, JavaScript經(jīng)典實例[M].李強,譯.北京:中國電力出版社,2012.
[14] CROCKFORD D. JavaScript 語言精粹[M].趙澤欣,鄢學(xué)鹍,譯.北京:電子工業(yè)出版社,2009.
Optimization of Ctrip Wireless H5 data storage based on Lizard framework
Du Yanren, Ge Huayong, Wang Long
(School of Information Science and Technology, Donghua University, Shanghai 201620, China)
Lizard is aimed at the present situation of the open source framework, applicable to wireless mobile development framework terminal by Ctrip. Lizard Web App is running in a Single Page on the Web browser Application (Single Page Application).We can put all loading resource on an HTML file. JavaScript can handle all user interaction. All communications are handled by Ajax. This article is based on the Lizard to realize Hybrid App (mixed mode mobile application) development, and improves the local store that has some problems in the Lizard.Thus we put forward a new improvement scheme that extended store way of storage, packaged store in polymorphic way.To support multiple localstorage methods we can replace cookie by LocalStorage,IndexDB,SQLite by App.
Lizard;Hybrid App;JavaScript;Web App;HTML;Ajax;data storage; wireless mobile development
TP311.1
A
10.19358/j.issn.1674- 7720.2016.11.005
2016-02-15)
杜燕忍(1990-),男,碩士研究生,主要研究方向:物聯(lián)網(wǎng)。
葛華勇(1976-),女,博士,副教授,碩士生導(dǎo)師,主要研究方向:信號與圖像處理。
王龍(1988-),男,本科,主要研究方向:無線開發(fā)。