PhoneGap開發(fā)實(shí)踐:豆瓣音樂人App
豆瓣音樂人app在2011年開發(fā)時(shí),便采用了基于原生與webapp混合架構(gòu)的PhoneGap框架,直到今天。這也是目前豆瓣唯一一款使用 PhoneGap的app。最近我們剛發(fā)布了音樂人app的ios新版,仍然保持這一架構(gòu),在原生方面的功能上做了一些增強(qiáng)。PhoneGap為音樂人 app的順利發(fā)布帶來很大幫助,當(dāng)然同時(shí)也造成了一些局限。
當(dāng)時(shí)如何做出使用PhoneGap的決定
我們之所以在技術(shù)選型時(shí)作出這一選擇,主要有以下幾個(gè)方面的原因:
-
開發(fā)效率的考慮
盡管豆瓣音樂人的用戶對app有很強(qiáng)的需求,但音樂人app的定位和發(fā)展方向,當(dāng)時(shí)處于不斷探索和快速迭代的階段,這樣的情況意味著,音樂產(chǎn)品線希望使用盡 可能簡單的方式、占用較少的人力資源進(jìn)行開發(fā),盡快在多個(gè)平臺發(fā)布,并且對于迭代的需求能夠快速響應(yīng)。在各種因素的權(quán)衡中,優(yōu)先考慮滿足上述需求。
對 于原生app好還是webapp好這個(gè)問題,似乎一直有很大爭議,實(shí)際上我不認(rèn)為這是一個(gè)純粹的技術(shù)問題。webapp在開發(fā)效率上的優(yōu)勢,原生app在 性能和開發(fā)自由度上的優(yōu)勢,都是不言自明的,一個(gè)app是否采用混合架構(gòu),在我看來,最重要的因素還是產(chǎn)品定位和發(fā)展策略,如果希望盡快發(fā)布、跨平臺、能 快速響應(yīng)可以預(yù)見的迭代,那么混合架構(gòu)就很值得考慮。如果有足夠的開發(fā)人員覆蓋各平臺、產(chǎn)品設(shè)計(jì)成熟度高、產(chǎn)品周期上可接受相對較長的開發(fā)時(shí)間,那么原生 顯然是更好的選擇。
-
跨平臺的考慮
豆瓣音樂人會是一個(gè)以展示內(nèi)容和收聽流媒體音樂為主的app,那些只有原生代碼才可以實(shí)現(xiàn)的功能,我們需要得比較少。這意味著,如果我們采用混合架構(gòu),需要實(shí)現(xiàn)的原生特性與需要解決的跨平臺問題會較少,混合架構(gòu)的優(yōu)勢會被放大。
即 使考慮了第一個(gè)因素后認(rèn)為值得使用混合架構(gòu),如果app本身的特性不適合webapp的方式,那也會顯得沒有這個(gè)必要。Webapp之所以開發(fā)效率高,一 方面在于html+css+js能做的事情,比用原生代碼做同樣的事情要簡單得多,另一方面在于方便跨平臺。如果app里面要實(shí)現(xiàn)的功能,很多都沒法用 html做,必須用原生代碼,那這兩方面的優(yōu)勢都消失殆盡。
實(shí)際上,就在我們第一個(gè)版本發(fā)布前不久,設(shè)計(jì)方面進(jìn)行了一次review,然后對app的整體外觀風(fēng)格和某些功能與交互做了大幅修改。但其實(shí)只用了幾天,設(shè)計(jì)的修改就被完全實(shí)現(xiàn)了,這樣的速度對web前端開發(fā)來說當(dāng)然不是什么難事,但對原生app來說卻是難以想象的。
App架構(gòu)與開發(fā)工作流
PhoneGap 只是個(gè)原生外殼,app的內(nèi)核是一個(gè)完整的webapp,需要調(diào)用的原生功能將以原生插件的形式實(shí)現(xiàn),以暴露js接口的方式調(diào)用。在webapp框架的選 擇上,我調(diào)研了當(dāng)時(shí)的一些專用于webapp的js框架,幾乎都不大成熟,沒什么合適的,當(dāng)然現(xiàn)在的情況已經(jīng)大不一樣了。由于音樂人app的規(guī)模不算大, 而且在移動設(shè)備的webview中性能非常重要,我決定把一些小工具組合成一套微型框架來使用,盡可能優(yōu)化執(zhí)行效率??蚣艽笾掠梢韵滦×慵M成:
- jQuery;
- iScroll4(模擬app風(fēng)格的滾動);
- js模板機(jī)制;
- url分發(fā)與訪問歷史管理;
- 頁面關(guān)系與頁面切換機(jī)制;
- 基于Jsonp的帶用戶認(rèn)證的api接口封裝。
這 樣就簡潔地實(shí)現(xiàn)了最小化的js框架。之所以使用jsonp的方式通信,是因?yàn)槲曳浅OM苁褂胏hrome進(jìn)行調(diào)試,這樣開發(fā)時(shí)就很方便,只需要雙擊本地 的html文件,chrome就會成為一個(gè)完美的移動設(shè)備模擬器,我可以使用自己喜歡的任意前端開發(fā)調(diào)試工作流,這比任何移動設(shè)備模擬器都要方便得多。
有了框架,接下來只需要一個(gè)頁面一個(gè)頁面實(shí)現(xiàn)就好了,我把webapp部分作為git submodule,ios和android的倉庫都包含它,打包時(shí)使用各自的編譯發(fā)布流程即可。
PhoneGap開發(fā)中遇到的問題
大致說一下遇到的印象深刻的問題。其實(shí)PhoneGap現(xiàn)在的版本已經(jīng)有很大改進(jìn),而且主流手機(jī)的性能已經(jīng)比以前好太多,現(xiàn)在新開發(fā)PhoneGap的話,應(yīng)該會輕松很多。
css3性能問題
我 們開始的設(shè)計(jì)中,有一些半透明和投影等效果,但我發(fā)現(xiàn)用css3實(shí)現(xiàn)后,會導(dǎo)致性能不好,這跟原生開發(fā)時(shí)可能遇到的半透明性能問題是一樣的。Webkit 并不如我們想象的那樣有保障。后來,我們?yōu)榇诵薷牧嗽O(shè)計(jì),盡可能使用不透明的元素,去掉投影等效果,并減少dom復(fù)雜度,性能得到了明顯提升。
像素密度問題
對 于不同像素密度的屏幕,需要準(zhǔn)備不同的圖片,然后在css里面使用媒體選擇器,根據(jù) –webkit-device-pixel-ratio,分別插入密度為0.75(老android手機(jī)),1(非retina iPhone),1.5(一些android手機(jī)),2(retina)的不同css,以使用不同的背景圖片。只需要修改一個(gè)css文 件,MakeFile腳本會自動生成其他的幾個(gè)css文件。當(dāng)然,我還需要保證這四套圖片是存在并且正確命名的。
Mp3播放問題
iOS 的webview支持mp3播放是沒有問題的,但當(dāng)時(shí)會有一個(gè)限制,就是如果用戶沒有主動操作,webview就不能自動開始播放,為它做一個(gè) workaround也就能夠解決了。比較麻煩的是android的某些較老的版本,雖然支持audio標(biāo)簽,但是不支持mp3格式的音頻,事實(shí)上它不支 持任何格式的音頻。所以對于這種情況,只能使用PhoneGap自帶的音頻播放功能。對用戶而言,效果是一樣的,但這增加了webapp的依賴,使 webapp部分變得復(fù)雜了。
不同系統(tǒng)的行為差異
雖然大體上來說,iOS和android使用的webview,其行為都是差不多的,而且由于都是webkit,樣式會非常接近,幾乎是自動完美跨平臺。但是實(shí)際開發(fā)中發(fā)現(xiàn),還是會有一些區(qū)別,例如:
- app ready時(shí)觸發(fā)的事件不一樣,當(dāng)然這和PhoneGap封裝有關(guān);
- android有時(shí)候會有軟鍵盤問題,有個(gè)插件可以解決;
- 處理打開外部url時(shí)行為不一致;
- 支持的動畫方式有區(qū)別,對不同平臺需要盡可能使用高效、硬加速的動畫方式。
- 需要為android的幾個(gè)實(shí)體按鍵寫專門的處理函數(shù)。
仍然需要編寫原生代碼
有的需求在webapp內(nèi)無法做到,這是經(jīng)常遇到的事。例如:
- 推送消息;
- 狀態(tài)欄提醒;
- 打開內(nèi)置瀏覽器訪問一些url;
- 綁定社交平臺賬號;
- 緩存下載的圖片和音樂等文件。
很 多都可以找到插件來解決,現(xiàn)在市面上的插件比當(dāng)時(shí)開發(fā)音樂人app最初版本時(shí),已經(jīng)豐富得多了,但仍然可能無法滿足需求,這時(shí)就需要自己寫插件來完成,每 出現(xiàn)一個(gè)這樣的需求,就意味著要為每個(gè)系統(tǒng)做一次原生解決方案。我們正準(zhǔn)備把音樂人app中使用的“推薦到社交平臺”的插件進(jìn)行開源,提供給其他有類似需 求的開發(fā)者使用。
可以移植到更多平臺,但也需要一些工作
我 簡單試過WebOS,樣式上會非常一致,但存在一些其他問題,為穩(wěn)定起見,我們沒有發(fā)布WebOS的打包。另外,移動版IE10已經(jīng)是對標(biāo)準(zhǔn)非常友好的瀏 覽器,但樣式上跟webkit仍然有差異,不能把webkit的webapp直接拿來就用,需要做適配。感覺上又回到了桌面web開發(fā)的世界。
有趣的是,使用MacGap把a(bǔ)pp核心部分打包成Mac的桌面應(yīng)用,倒是完全無痛,幾乎直接就可以用。
總結(jié)
使用感覺上來說, iOS上的效果要略好于Android上的效果,幾乎跟原生界面沒太大區(qū)別。雖然跟原生app相比,渲染速度等細(xì)節(jié)上仍然略微吃虧,但總的看來是完全可以接受的水平。
總結(jié)一下的話,我們對基于PhoneGap得到的成果是滿意的,開發(fā)性價(jià)比很高。用戶對音樂人app的評價(jià)也比較好。將來在產(chǎn)品穩(wěn)定后,我們是否會使用純原生app替代PhoneGap,現(xiàn)在還不知道,這將取決于產(chǎn)品未來的決策。希望得到什么,也就同時(shí)決定了會放棄什么,一切都是權(quán)衡的結(jié)果,框架沒有銀彈。