2017年1月9日,微信官方在2017微信公開課Pro上發佈的小程序正式上線,開創了小程序開發的時代。咱們的美團外賣的業務也逐步加入到小程序開發的隊伍中。小程序有着無需安裝、觸手可及、用完即走、無須卸載的特色,屬於「輕」量級的應用。前端
可是這樣的「輕」量級應用卻承載咱們很是複雜的外賣業務,對於咱們外賣團隊來講,也面臨着不少新的機遇和挑戰。本文將詳細介紹咱們外賣小程序的解決方案與經驗,但願可以對你們有所啓發。本次分享主要由如下四個部分展開:vue
小程序發佈時,其定位主要是功能比較簡單的輕應用,因此原生框架設計相對比較簡單,而對於業務相對複雜的中大型互聯網企業,小程序產品支持還不夠完善,項目較難進行管理和維護。npm
針對業務場景的多樣性,咱們採用了較開放的框架策略:項目既支持原生框架開發,又支持自由引入第三方框架,以知足各業務場景的需求。gulp
原生框架開發:對主流程等相對獨立且穩定性要求高的業務採用了原生框架進行開發。小程序
支持mpvue(第三方框架):營銷業務須要支持Web頁、小程序頁等多種渠道,經過引入mpvue,可使各渠道複用Vue組件,進而提高開發效率。後端
針對咱們面對的業務場景,咱們將各業務通用的基礎功能進行了梳理,抽離成一些組件來進行統一管理和維護。高複用性組件可以有效提高開發效率,並且研發質量也能夠獲得很好的保障。微信小程序
多團隊合做開發小程序的模式下,咱們將核心的主流程業務放在主包,其餘各業務都存放在各自子包當中。這樣作的目的,是確保每一個包中的業務相關性較強,避免了用戶使用中會有頻繁的子包模塊加載過程,也能保證各業務團隊之間的隔離,避免出現業務衝突。緩存
咱們的通用組件和各業務子包都託管在npm上,而後進行模塊化的管理。並經過對構建腳本的改造,將npm引入到小程序主包中,進一步保證各業務間的隔離性,以下圖所示:服務器
同時咱們在小程序開發週期中,制定了版本管理、准入流程、發佈流程等,規範化小程序各環境版本的使用,進一步確保各團隊間的順暢合做。總體架構圖以下圖所示: 微信
咱們的系統架構,最底層是微信小程序的原生API,中層是各業務通用的核心組件,如登錄、WebView封裝組件、監控、數據上報等,均由統一的團隊建設和維護。對編譯構建工具進行插件化改造,能夠自由引入第三方框架進行開發。最上層是各業務方經過拆包將業務隔離開來。
在本地開發過程的整個構建流程以下圖所示。開發者在本地工做目錄執行操做,經過gulp構建目標文件到本地工做目錄中,再經過微信開發者工具對生成的代碼進行調試和發佈。同時咱們的構建支持Mock服務,模擬後端服務器接口,提升聯調效率。
咱們的發佈規範過程以下圖所示。和通常的前端發佈過程相似,差別點在於必須通過微信開發工具才能上傳代碼進行微信方的審覈與發佈。
而咱們的指望和後期規劃是將整個CI構建和發佈過程一體化。以下圖所示:
近期微信開發者工具提供了命令行工具和HTTP方式來支持小程序的預覽和上傳,咱們正在將整個流程進行整合與改造。經過在服務器中安裝微信開發者工具,將整個過程使用CI鏈接起來,減小人工操做的過程,來提高發布流程的效率和質量。
不過在實現徹底自動化發佈的道路上依然面臨着一些問題:
小程序原生框架對於模塊和組件的支持也處在不斷完善的過程當中。最先小程序框架支持CommonJS規範,可使用require、module關鍵詞定義和引入js模塊,支持經過@import來引入樣式文件,支持在佈局文件wxml中支持定義template模板,能夠經過include、import和wxs等標籤引用外部文件。
而實現一個組件,經常wxs邏輯,wxss樣式和wxml佈局三個文件都須要進行定義,這就意味着引用一個組件時,須要在三個文件中同時引入。組件獨立性差,與頁面文件高耦合,不利於開發和維護,使用起來很是不便。
所以在基礎庫1.6.3版本中,小程序開始支持自定義組件,只須要經過標籤就能夠很方便的引入本身開發的組件。但早期的自定義組件版本,只容許綁定JSON兼容格式的數據,並不支持回調函數,在使用上存在很大侷限性。直到2.0.9版本纔開始支持函數傳入。
近期,小程序原生支持了npm,但基礎版本庫要求在2.2.1及以上,而且須要經過微信開發者工具進行一遍構建。整體來講,小程序框架在不斷完善對組件的支持,但若是考慮低版本用戶的兼容性,開發者開始有較多工做要作。
咱們將組件劃分爲三種類型,頁面組件、UI組件、功能組件。
咱們基於微信組件的演化也在擴充和完善咱們的通用組件過程當中,同時也相同存在着一些侷限性,以後針對通用組件的關注方向主要在如下兩方面:
大小約100k隨機對象讀寫清空緩存各100次,小程序Storage與Web LocalStorage 耗時比較以下圖所示:
可見小程序的性能遠低於Webview的LocalStorage,因此針對這樣的現狀,咱們Storage組件的封裝與設計必須重點考慮性能問題的解決與規避。
針對小程序Storage的讀寫性能差,且存儲量有限的狀況下,咱們Storage的設計有如下特色:
整個流程以下圖所示:
防止誤調用底層API致使數據不一樣步:
目前小程序開發工具也在不斷完善中,最近增長了不少諸如npm 支持、命令行調用、HTTP調用、Git版本管理、雲開發、體驗評分等功能,工具的完善爲開發者帶來了必定便利。
小程序的特殊性致使小程序開發人員與微信提供的開發工具的強粘黏性,能夠感知到微信小程序開發工具的設計是指望實現一個小程序開發的閉環。
但這樣的一個「黑盒」工具也存在着必定問題——沒法知足不一樣團隊和業務的一些需求。因此咱們也但願,將來小程序開發工具能提供一些工具開放功能的API,咱們能夠對開放功能進行改造實現,最終知足各個團隊不一樣的需求。
同時小程序在最初的定位(功能比較簡單的輕應用)和設計下,性能不會過高。若是承載較大型複雜的業務,勢必會遇到一些性能問題,因此性能問題的關注是比較重要的。官方對於性能問題在開發上的建議是控制setData 的數據體積大小、控制setData的頻率。但真實的業務場景中有不少是沒法避免頻繁setData的,如對滑動操做(較高頻的動做)後的一些特殊需求、複雜頁面點擊快速響應等。
美團外賣在基於這些問題的規劃包括:
此外,與性能並存的一個問題是小程序體積的限制(不超過2M,包含子包的主包,總包不超過8M)。這樣的限制有必定道理,由於小程序渲染前,須要通過下載整個小程序的包體、後端請求數據、對數據進行渲染這樣相對較長的週期,包體過大必然影響用戶感知渲染的時間,影響用戶體驗。
減少體積的規劃採起方案包括:
這兩大重點問題在咱們的業務場景和當前架構設計下,都是將來長期須要關注和解決的問題。
咱們複雜的業務在開發小程序時雖然面臨着這樣一些問題:「輕」量應用的小程序對於較大型的應用和較複雜的業務場景存在着必定的侷限性,「輕」量理念的原生框架稍簡單,不足以完美支撐咱們較大型和複雜的業務;多團隊合做如何保證高效性;如何更友好地知足不一樣的業務場景。
最終咱們經過在技術框架層面優化設計和規避一些小程序侷限性問題,制定更合理的流程和建設更強大的工具來提升工做效率,基於微信小程序組件化演進建設咱們的組件化生態,來解決咱們所面臨的問題。同時也對微信小程序工具、性能、體積等方面進行展望和規劃咱們的後續進程,保持咱們的深度探索和實踐。