編者按:本文轉(zhuǎn)載自美團技術(shù)團隊掘金專欄

2017年1月9日,微信官方在2017微信公開課Pro上發(fā)布的小程序正式上線,開創(chuàng)了小程序開發(fā)的時代。我們的美團外賣的業(yè)務(wù)也逐步加入到小程序開發(fā)的隊伍中。小程序有著無需安裝、觸手可及、用完即走、無須卸載的特點,屬于“輕”量級的應(yīng)用。

但是這樣的“輕”量級應(yīng)用卻承載我們非常復雜的外賣業(yè)務(wù),對于我們外賣團隊來說,也面臨著很多新的機遇和挑戰(zhàn)。本文將詳細介紹我們外賣小程序的解決方案與經(jīng)驗,希望能夠?qū)Υ蠹矣兴鶈l(fā)。本次分享主要由以下四個部分展開:

第一部分:技術(shù)架構(gòu)

小程序發(fā)布時,其定位主要是功能比較簡單的輕應(yīng)用,所以原生框架設(shè)計相對比較簡單,而對于業(yè)務(wù)相對復雜的中大型互聯(lián)網(wǎng)企業(yè),小程序產(chǎn)品支持還不夠完善,項目較難進行管理和維護。

而美團外賣小程序按照業(yè)務(wù)、主流程、營銷、廣告等劃分了多個團隊共同進行開發(fā),如何保證多團隊高效協(xié)同地開發(fā)小程序就是一個難題;同時在美團外賣小程序中,主流程要求穩(wěn)定增量更新,營銷活動則需要快速迭代多渠道支持,針對不同的業(yè)務(wù)場景需求,如何去做好支持工作也是非常重要的一環(huán)。那么如何應(yīng)對這些挑戰(zhàn)呢?

業(yè)務(wù)場景

針對業(yè)務(wù)場景的多樣性,我們采用了較開放的框架策略:項目既支持原生框架開發(fā),又支持自由引入第三方框架,以滿足各業(yè)務(wù)場景的需求。

原生框架開發(fā):對主流程等相對獨立且穩(wěn)定性要求高的業(yè)務(wù)采用了原生框架進行開發(fā)。

一方面,我們考慮小程序原生框架不夠完善,隨著基礎(chǔ)版本庫的升級,存在需要處理的兼容性問題,避免引入第三方框架增加調(diào)試難度或引入新的問題。

另一方面,小程序代碼體積限制比較嚴格,避免引入第三方框架在編譯過程中引入較大的框架代碼。

支持mpvue:營銷業(yè)務(wù)需要支持Web頁、小程序頁等多種渠道,通過引入mpvue,可以使各渠道復用Vue組件,進而提升開發(fā)效率。

通用組件

針對我們面對的業(yè)務(wù)場景,我們將各業(yè)務(wù)通用的基礎(chǔ)功能進行了梳理,抽離成一些組件來進行統(tǒng)一管理和維護。高復用性組件能夠有效提升開發(fā)效率,而且研發(fā)質(zhì)量也可以得到很好的保障。

協(xié)同開發(fā)

多團隊合作開發(fā)小程序的模式下,我們將核心的主流程業(yè)務(wù)放在主包,其他各業(yè)務(wù)都存放在各自子包當中。這樣做的目的,是確保每個包中的業(yè)務(wù)相關(guān)性較強,避免了用戶使用中會有頻繁的子包模塊加載過程,也能保證各業(yè)務(wù)團隊之間的隔離,避免出現(xiàn)業(yè)務(wù)沖突。

我們的通用組件和各業(yè)務(wù)子包都托管在npm上,然后進行模塊化的管理。并通過對構(gòu)建腳本的改造,將npm引入到小程序主包中,進一步保證各業(yè)務(wù)間的隔離性,如下圖所示:

同時我們在小程序開發(fā)周期中,制定了版本管理、準入流程、發(fā)布流程等,規(guī)范化小程序各環(huán)境版本的使用,進一步確保各團隊間的順暢合作。整體架構(gòu)圖如下圖所示:

第二部分:流程與工具

工具規(guī)范方面:我們提供了子包項目、組件創(chuàng)建腳手架。比如登陸、WebView等通用組件以及業(yè)務(wù)組件都使用我們的組件腳手架來進行創(chuàng)建,簡化并較低成本規(guī)范了子包項目搭建和構(gòu)建過程,提升項目搭建效率與合作效率。

測試方面:我們?yōu)榻M件接入了單元測試。小程序整個項目的單元測試和UI的自動化測試也在建設(shè)中。我們在小程序開發(fā)周期中,制定了版本管理、準入流程、發(fā)布流程等,規(guī)范化小程序各環(huán)境版本的使用,進一步確保各團隊間的順暢合作。

開發(fā)過程

在本地開發(fā)過程的整個構(gòu)建流程如下圖所示。開發(fā)者在本地工作目錄執(zhí)行操作,通過gulp構(gòu)建目標文件到本地工作目錄中,再通過微信開發(fā)者工具對生成的代碼進行調(diào)試和發(fā)布。同時我們的構(gòu)建支持Mock服務(wù),模擬后端服務(wù)器接口,提高聯(lián)調(diào)效率。

發(fā)布過程

我們的發(fā)布規(guī)范過程如下圖所示。和一般的前端發(fā)布過程類似,差異點在于必須經(jīng)過微信開發(fā)工具才能上傳代碼進行微信方的審核與發(fā)布。

而我們的期望和后期規(guī)劃是將整個CI構(gòu)建和發(fā)布過程一體化。如下圖所示:

近期微信開發(fā)者工具提供了命令行工具和HTTP方式來支持小程序的預覽和上傳,我們正在將整個流程進行整合與改造。通過在服務(wù)器中安裝微信開發(fā)者工具,將整個過程使用CI連接起來,減少人工操作的過程,來提升發(fā)布流程的效率和質(zhì)量。

不過在實現(xiàn)完全自動化發(fā)布的道路上依然面臨著一些問題:

開發(fā)者工具的登陸,公眾后臺的提交審核和發(fā)布都需要人工介入。

由于微信開發(fā)者工具目前僅有macOS和Windows兩個版本,而CI服務(wù)器大多是在Linux系統(tǒng)上,還需要額外啟動服務(wù)器來部署開發(fā)者工具,改造過程也相對復雜。

第三部分:組件化

原生組件化演進

小程序原生框架對于模塊和組件的支持也處在不斷完善的過程中。最早小程序框架支持CommonJS規(guī)范,可以使用require、module關(guān)鍵詞定義和引入js模塊,支持通過@import來引入樣式文件,支持在布局文件wxml中支持定義template模板,可以通過include、import和wxs等標簽引用外部文件。

而實現(xiàn)一個組件,常常wxs邏輯,wxss樣式和wxml布局三個文件都需要進行定義,這就意味著引用一個組件時,需要在三個文件中同時引入。組件獨立性差,與頁面文件高耦合,不利于開發(fā)和維護,使用起來非常不便。

因此在基礎(chǔ)庫1.6.3版本中,小程序開始支持自定義組件,只需要通過標簽就可以很方便的引入自己開發(fā)的組件。但早期的自定義組件版本,只允許綁定JSON兼容格式的數(shù)據(jù),并不支持回調(diào)函數(shù),在使用上存在很大局限性。直到2.0.9版本才開始支持函數(shù)傳入。

近期,小程序原生支持了npm,但基礎(chǔ)版本庫要求在2.2.1及以上,并且需要通過微信開發(fā)者工具進行一遍構(gòu)建??傮w來說,小程序框架在不斷完善對組件的支持,但如果考慮低版本用戶的兼容性,開發(fā)者開始有較多工作要做。

組件分類

我們將組件劃分為三種類型,頁面組件、UI組件、功能組件。頁面組件:功能相對比較獨立的頁面,如用于內(nèi)嵌H5的WebView封裝頁面等;

UI組件:頁面中局部功能較獨立的UI部分,比如頁面中嵌入的登陸組件,商家列表等;

功能組件指:無UI和交互,純JS的模塊。

通用組件關(guān)注方向

我們基于微信組件的演化也在擴充和完善我們的通用組件過程中,同時也相同存在著一些局限性,之后針對通用組件的關(guān)注方向主要在以下兩方面:

小程序組件原生功能的補充和完善。

通用基礎(chǔ)及業(yè)務(wù)功能統(tǒng)一封裝。

Storage組件

大小約100k隨機對象讀寫清空緩存各100次,小程序Storage與Web LocalStorage 耗時比較如下圖所示:

可見小程序的性能遠低于Webview的LocalStorage,所以針對這樣的現(xiàn)狀,我們Storage組件的封裝與設(shè)計必須重點考慮性能問題的解決與規(guī)避。

Storage組件優(yōu)化

針對小程序Storage的讀寫性能差,且存儲量有限的情況下,我們Storage的設(shè)計有以下特點:

內(nèi)存高性能讀寫數(shù)據(jù):利用內(nèi)存存儲數(shù)據(jù)替代大量數(shù)據(jù)存在小程序Storage中,從而規(guī)避Storage讀寫操作的性能瓶頸,同時減輕存儲量的占用率。

文件持久化存儲:采用內(nèi)存與Storage相結(jié)合的形式,保證緩存數(shù)據(jù)的可用性。

數(shù)據(jù)同步:由于持久化的策略,所以需要有完整并保證準確性的流程來同步內(nèi)存數(shù)據(jù)與Storage數(shù)據(jù)。

整個流程如下圖所示:

防止誤調(diào)用底層API導致數(shù)據(jù)不同步:

寫入文件時key追加特殊前綴

編譯時進行語法檢查,誤調(diào)用及時告警

第四部分:展望與規(guī)劃

目前小程序開發(fā)工具也在不斷完善中,最近增加了很多諸如npm 支持、命令行調(diào)用、HTTP調(diào)用、Git版本管理、云開發(fā)、體驗評分等功能,工具的完善為開發(fā)者帶來了一定便利。

小程序的特殊性導致小程序開發(fā)人員與微信提供的開發(fā)工具的強粘黏性,可以感知到微信小程序開發(fā)工具的設(shè)計是期望實現(xiàn)一個小程序開發(fā)的閉環(huán)。

但這樣的一個“黑盒”工具也存在著一定問題——無法滿足不同團隊和業(yè)務(wù)的一些需求。所以我們也希望,未來小程序開發(fā)工具能提供一些工具開放功能的API,我們可以對開放功能進行改造實現(xiàn),最終滿足各個團隊不同的需求。

同時小程序在最初的定位和設(shè)計下,性能不會太高。如果承載較大型復雜的業(yè)務(wù),勢必會遇到一些性能問題,所以性能問題的關(guān)注是比較重要的。官方對于性能問題在開發(fā)上的建議是控制setData 的數(shù)據(jù)體積大小、控制setData的頻率。但真實的業(yè)務(wù)場景中有很多是無法避免頻繁setData的,如對滑動操作后的一些特殊需求、復雜頁面點擊快速響應(yīng)等。

美團外賣在基于這些問題的規(guī)劃包括:

小程序性能的測試指標定制:及時發(fā)現(xiàn)項目的性能瓶頸,進行有針對性的優(yōu)化。經(jīng)過測試小程序渲染數(shù)據(jù)達到100Kb時卡頓明顯,尤其在安卓手機,所以其中就包括對渲染數(shù)據(jù)大小制定一定指標。

性能分析工具:開發(fā)一些工具對性能進行分析。

框架優(yōu)化:從框架層來針對性規(guī)避遇到的一些問題。

長列表組件的實現(xiàn):使用官方提供的長列表組件。

此外,與性能并存的一個問題是小程序體積的限制。這樣的限制有一定道理,因為小程序渲染前,需要經(jīng)過下載整個小程序的包體、后端請求數(shù)據(jù)、對數(shù)據(jù)進行渲染這樣相對較長的周期,包體過大必然影響用戶感知渲染的時間,影響用戶體驗。

減小體積的規(guī)劃采取方案包括:

npm依賴優(yōu)化:npm包之間內(nèi)部的依賴包會存在重復的情況,重復的部分都占用包體積,采取對代碼預解析簡化npm包代碼來縮小包體。

圖片部署CDN:圖片體積占包較大,非關(guān)鍵圖片部署到CDN。

非關(guān)鍵頁面遷移子包:采用子包、獨立子包的方式減少對主包體積的占用。

頁面動態(tài)下發(fā):小程序不支持動態(tài)下發(fā)功能,目前我們正在探索和考慮。

這兩大重點問題在我們的業(yè)務(wù)場景和當前架構(gòu)設(shè)計下,都是未來長期需要關(guān)注和解決的問題。

總結(jié)

我們復雜的業(yè)務(wù)在開發(fā)小程序時雖然面臨著這樣一些問題:“輕”量應(yīng)用的小程序?qū)τ谳^大型的應(yīng)用和較復雜的業(yè)務(wù)場景存在著一定的局限性,“輕”量理念的原生框架稍簡單,不足以完美支撐我們較大型和復雜的業(yè)務(wù);多團隊合作如何保證高效性;如何更友好地滿足不同的業(yè)務(wù)場景。

最終我們通過在技術(shù)框架層面優(yōu)化設(shè)計和規(guī)避一些小程序局限性問題,制定更合理的流程和建設(shè)更強大的工具來提高工作效率,基于微信小程序組件化演進建設(shè)我們的組件化生態(tài),來解決我們所面臨的問題。同時也對微信小程序工具、性能、體積等方面進行展望和規(guī)劃我們的后續(xù)進程,保持我們的深度探索和實踐。

關(guān)于奇舞周刊

《奇舞周刊》是360公司專業(yè)前端團隊「奇舞團」運營的前端技術(shù)社區(qū)。關(guān)注公眾號后,直接發(fā)送鏈接到后臺即可給我們投稿。

1.《外賣小程序 美團外賣小程序的探索和實踐》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。

2.《外賣小程序 美團外賣小程序的探索和實踐》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。

3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/guonei/31312.html