Mpx是一款致力於提高小程序開發體驗的增強型小程序框架,通過Mpx,我們能夠以最先進的web開發體驗(Vue + Webpack)來開發生產性能深度優化的小程序,Mpx具有以下一些優秀特性:

  • 數據響應特性(watch/computed)
  • 增強的模板語法(動態組件/樣式綁定/類名綁定/內聯事件函數/雙向綁定等)
  • 深度性能優化(原生自定義組件/基於依賴收集和數據變化的setData)
  • Webpack編譯(npm/循環依賴/Babel/ESLint/css預編譯/代碼優化等)
  • 單文件組件開發
  • 狀態管理(Vuex規範/多實例/可合併)
  • 跨團隊合作(packages)
  • 邏輯復用能力(mixins)
  • 腳手架支持
  • 小程序自身規範的完全支持
  • 支付寶小程序的支持

設計思路

目前業界主流的小程序框架主要有WePY,mpvue和Taro,這三者都是將其他的語法規範轉譯為小程序語法規範,我們稱其為轉譯型框架。不同於上述三者,Mpx是一款基於小程序語法規範的增強型框架,我們使用Vue中優秀的語法特性增強了小程序,而不是讓用戶直接使用vue語法來開發小程序,之所以採用這種設計主要是基於如下考慮:

  • 轉譯型框架無法支持源框架的所有語法特性(如Vue模板中的動態特性或React中動態生成的jsx),用戶在使用源框架語法進行開發時可能會遇到不可預期的錯誤,具有不確定性
  • 小程序本身的技術規範在不斷地更新進步,許多新的技術規範在轉譯型框架中無法支持或需要很高的支持成本,而對於增強型框架來說只要新的技術規範不與增強特性衝突,就能夠直接支持

技術實現

小程序剛推出時不支持自定義組件,無法進行組件化開發,WePY和mpvue做了一系列的工作來支持了這一關鍵特性,大大提高了用戶的開發體驗和效率。WePY和mpvue的組件化支持是基於編譯做的組件化封裝,用戶編寫的組件模板會被編譯為Page中模板的一部分,在組件中定義的數據會被編譯為Page中的數據,對組件進行數據更新也會基於路徑映射調用Page.setData。這在當時的技術條件下是很棒的技術方案,但該方案在複雜的小程序應用中存在性能問題,原因在於該方案中頁面的數據量會很大,而且每個組件的局部更新實際上都會成為頁面級別的全局更新,在組件較多的頁面中產生很大的性能開銷。

在小程序自定義組件推出後,我們通過性能測試確認了小程序自定義組件支持組件級別的局部更新,具有良好的更新性能。由於自定義組件在當時是最新的技術標準,業內的小程序框架都未支持,而我們在業務上又有複雜小程序的開發需求,於是我們就基於小程序自定義組件啟動了Mpx框架的設計與開發

Page與Component setData性能對照

egin{array}{c|c} & 	ext{Component} &	ext{Page} \ hline 局部更新 & 1975ms & 7186ms\ 全局更新 & 6210ms & 24612ms\ end{array}

性能衡量標準說明:

局部更新:文檔中存在1000個節點,其中一個節點更新1000次的耗時; 全局更新:文檔中存在5個節點,5個節點獨立更新1000次的耗時 以上數據在iphone7微信小程序環境下測試得出

數據響應與性能優化

數據響應作為Vue最核心的特性,在我們的日常開發中被大量使用,能夠極大地提高前端開發體驗和效率,我們在框架設計初期最早考慮的就是如何將數據響應特性加入到小程序開發中。在數據響應的實現上,我們引入了MobX,一個實現了純粹數據響應能力的知名開源項目。藉助MobX和mixins,我們在小程序組件創建初期建立了一個響應式數據管理系統,該系統觀察著小程序組件中的所有數據(data/props/computed)並基於數據的變更驅動視圖的渲染(setData)及用戶註冊的watch回調,實現了Vue中的數據響應編程體驗。與此同時,我們基於MobX封裝實現了一個Vuex規範的數據管理store,能夠方便地注入組件進行全局數據管理。為了提高跨團隊開發的體驗,我們對store添加了多實例可合併的特性,不同團隊維護自己的store,在需要時能夠合併他人或者公共的store生成新的store實例,我們認為這是一種比Vuex中modules更加靈活便捷的跨團隊數據管理模式

作為一個接管了小程序setData的數據響應開發框架,我們高度重視Mpx的渲染性能,通過小程序官方文檔中提到的性能優化建議可以得知,setData對於小程序性能來說是重中之重,setData優化的方向主要有兩個:

  1. 儘可能減少setData調用的頻次
  2. 儘可能減少單次setData傳輸的數據

為了實現以上兩個優化方向,我們做了以下幾項工作:

  • 將組件的靜態模板編譯為可執行的render函數,通過render函數收集模板數據依賴,只有當render函數中的依賴數據發生變化時才會觸發小程序組件的setData,同時通過一個非同步隊列確保一個tick中最多隻會進行一次setData,這個機制和Vue中的render機制非常類似,大大降低了setData的調用頻次;
  • 將模板編譯render函數的過程中,我們還記錄輸出了模板中使用的數據路徑,在每次需要setData時會根據這些數據路徑與上一次的數據進行diff,僅將發生變化的數據通過數據路徑的方式進行setData,這樣確保了每次setData傳輸的數據量最低,同時避免了不必要的setData操作,進一步降低了setData的頻次。

基於以上優化,我們大大減少了小程序setData的調用頻次和傳遞數據量,與初版Mpx中track全量數據的方案相比提示顯著。

Mpx setData優化效果

egin{array}{c|c} & 	ext{舊版Mpx} &	ext{新版Mpx} \ hline setData次數 & 164 & 88\ setData數據量 & 370kB & 38kB\ end{array}

以上數據由較複雜小程序在固定交互流程後統計得出

Mpx數據響應機制流程示意圖

編譯構建

我們希望使用目前設計最強大、生態最完善的編譯構建工具Webpack來實現小程序的編譯構建,讓用戶得到web開發中先進強大的工程化開發體驗。使用過Webpack的同學都知道,通常來說Webpack都是將項目中使用到的一系列碎片化模塊打包為一個或幾個bundle,而小程序所需要的文件結構是非常離散化的,如何調解這兩者的矛盾成為了我們最大的難題。一種非常直觀簡單的思路在於遍歷整個src目錄,將其中的每一個.mpx文件都作為一個entry加入到Webpack中進行處理,這樣做的問題主要有兩個:

  1. src目錄中用不到的.mpx文件也會被編譯輸出,最終也會被小程序打包進項目包中,無意義地增加了包體積;
  2. 對於node_modules下的.mpx文件,我們不認為遍歷node_modules是一個好的選擇。

最終我們採用了一種基於依賴分析和動態添加entry的方式來進行實現,用戶在Webpack配置中只需要配置一個入口文件app.mpx,loader在解析到json時會解析json中pages域和usingComponents域中聲明的路徑,通過動態添加entry的方式將這些文件添加到Webpack的構建系統當中(注意這裡是添加entry而不是添加依賴,因為只有entry能生成獨立的文件,滿足小程序的離散化文件結構),並遞歸執行這個過程,直到整個項目中所有用到的.mpx文件都加入進來,在輸出前,我們藉助了CommonsChunkPlugin/SplitChunksPlugin的能力將復用的模塊抽取到一個外部的bundle中,確保最終生成的包中不包含重複模塊。我們提供了一個Webpack插件和一個.mpx文件對應的loader來實現上述操作,用戶只需要將其添加到Webpack配置中就可以以打包web項目的方式正常打包小程序,沒有任何的前置和後置操作,支持Webpack本身的完整生態。

Mpx編譯構建機制流程示意圖

現狀和未來

目前Mpx框架已經在滴滴內部大量使用,支撐了滴滴出行、青桔單車、街兔電單車、營銷、車服等業務在小程序上的實現,線上運行穩定,收到了大量的好評反饋。未來我們在對框架進行持續迭代優化的同時會持續跟進微信和支付寶最新的技術標準,同時也會將在更多的小程序平臺上進行適配。由於我們的設計初衷和專註點在於增強小程序開發體驗,Mpx並沒有進行跨H5甚至是跨Native的支持,但現實業務當中確實存在這樣的訴求,未來我們會在Mpx的基礎上對跨端進行一定的嘗試,與此同時我們依然會持續維護升級Mpx,原因在於跨端意味著靈活性受限及能力的缺失,我們希望能給用戶提供第二種選擇。

Mpx與業內主流小程序框架異同對比

egin{array}{c|c} & 	ext{WePY} &	ext{mpvue} &	ext{Taro} &	ext{Mpx}  \ hline 代碼規範 & 自定義 & Vue & React & 小程序+\ 組件化實現 & Page封裝 & Page封裝 & Component & Component\ 數據響應 & 臟值檢查 & Vue & 無 & Mobx\ 狀態管理 & Redux & Vuex & Redux &類Vuex\ end{array}

結語

如果你注重開發體驗和產品性能,專註於小程序開發,那Mpx會是一個很好的選擇。最後感謝開源社區源源不斷湧現出的優秀項目,給我們提供了無限的啟發和巨大的技術幫助。

Github: github.com/didi/mpx

使用文檔: didi.github.io/mpx/

用戶交流: 點我進羣


推薦閱讀:
相關文章