上週,Taro 團隊釋出了一篇《小程式多端框架全面測評》,讓開發者對業界主流的跨端框架,有了初步認識。感謝 Taro 團隊的付出。
不過橫評這件事,要想做完善,其實非常花費時間。不是隻看文件就行,它需要:
- 真實的動手寫多個平臺的測試demo,比較各個平臺的功能、效能,它們的實際情況到底是不是如文件宣傳的那樣?
- 真實的學習每個框架,瞭解它們的學習曲線,在實際開發中遇到問題時,感受它們的文件、教程、社群生態和技服能力到底怎麼樣?
我們 uni-app
團隊投入一週完成了這個深度評測,下面我們就分享下,實際開發不同框架的測試例遇到的問題,和最終的測試結果。
評測實驗介紹
-
開發內容:開發一個仿微博小程式首頁的複雜長列表,支援下拉重新整理、上拉翻頁、點贊。
-
介面如下:
-
開發版本:一共開發了6個版本,包括微信原生版、wepy版、mpvue版、taro版、uni-app版、chameleon版(以這些產品釋出時間排序,下同),按照官網指引通過
cli
方式預設安裝(應該是最新穩定版)。 -
測試程式碼開源(Github倉庫地址:https://github.com/dcloudio/test-framework), Tips:若有同學覺得測試程式碼寫法欠妥,歡迎提交 PR 或 Issus
-
測試機型:紅米 Redmi 6 Pro、MIUI 10.2.2.0 穩定版(最新版)、微信版本 7.0.3(最新版)
-
測試環境:每個框架開始測試前,殺掉各App程式、清空記憶體,保證測試機環境基本一致;每次從本地讀取靜態資料,遮蔽網路差異。
-
測試維度:
- 跨端支援度如何?
- 效能如何?
- 學習門檻
- 工具與周邊生態
1. 跨端支援度如何
開發一次,到處執行,是每個程式設計師的夢想。但現實往往變成開發一次,到處調錯。
各個待評測框架,是否真得如宣傳的那樣,一次開發、多端釋出?
我們將上述仿微博App依次釋出到各平臺,驗證每個框架在各端的相容性,結果如下(表格較長,需左右滾動檢視):
平臺 | 微信原生 | wepy | mpvue | taro | uni-app | chameleon |
---|---|---|---|---|---|---|
微信小程式 | ⭕️ | ⭕️ | ⭕️ | ⭕️ | ⭕️ | ⭕️ |
支付寶小程式 | ❌ | ❌ | ⭕️ | ⭕️ | ⭕️ | ❌ |
百度小程式 | ❌ | ❌ | ⭕️ | ⭕️ | ⭕️ | ❌ |
頭條小程式 | ❌ | ❌ | ⭕️ | ⭕️ | ⭕️ | ❌ |
H5端 | ❌ | ❌ | ❌ | 上拉載入/下拉重新整理失效 | ⭕️ | 上拉載入/下拉重新整理失效 |
App端 | ❌ | ❌ | ❌ | 上拉載入失效 | ⭕️ | 列表無法滾動,無法測試上拉載入/下拉重新整理 |
測試結果說明:
- ⭕ 表示支援且功能正常,❌ 表示不支援,其它則表示支援但存在部分bug或相容問題
wepy
2.0 宣稱版已支援其他家小程式,本測試基於wepy
官網指引安裝的wepy-cli
預設版本為1.7.3,尚不支援多端chameleon
嚐鮮版宣稱支付寶、百度小程式,本測試基於chameleon
官網指引安裝的chameleon-tool
預設版本為0.1.1,尚不支援其它小程式
通過這個簡單的例子可以看出,跨端支援度測評結論:uni-app
> taro
> chameleon
> mpvue
>wepy
、原生微信小程式
但是僅有上面的測試還不全面,實際業務要比這個測試例複雜很多。但我們沒法開發很多複雜業務做評測,所以還需要再對照各家文件補充一些資訊。 由於每個框架的文件中都描述了各種元件和API的跨端支援程度。我們過了幾家的文件,發現各家基本是以微信小程式為基線,然後把各種元件和API在其他端實現了一遍:
taro
:H5端實現了大部分微信的API,App端和微信的差異比較大。uni-app
:元件、API、配置,大部分在各個端均已實現,個別API有說明在某些端不支援。可以看出uni-app是完整在H5端實現了一套微信模擬器,在App端實現了一套微信小程式引擎,才達到比較完善的平臺相容性。chameleon
:非常常用的一些元件和API在各端已經實現,這部分的平臺差異較少。但大量元件和API需要開發者自己分平臺寫程式碼。
跨端框架,一方面要考慮框架提供的通用api跨端支援,同時還要考慮不同端的特色差異如何相容。畢竟每個端都會有自己的特色,不可能完全一致。
taro
:提供了js環境變數判斷和統一介面的多端檔案,可以在元件、js、檔案方面擴充套件多端,不支援其他環節的分平臺處理。uni-app
:提供了條件編譯模型,所有程式碼包括元件、js、css、配置json、檔案、目錄,均支援條件編譯,可不受限的編寫各端差異程式碼。chameleon
:提供了多型方案,可以在元件、js、檔案方面擴充套件多端,不支援其他方式的分平臺處理。
跨端框架,還涉及一個ui框架的跨端問題,評測結果如下:
taro
:官方提供了taro ui
,只支援微信小程式和H5兩端,不支援App,詳見uni-app
:官方提供了uni ui
,可全端執行;uni-app還有一個外掛市場,裡面有很多三方ui元件,詳見chameleon
:官方提供了cml-ui
擴充套件元件庫,可全端執行,但元件數量略少,詳見
最後補充跨端案例:
- mpvue:微信端案例豐富,未見其它端案例
- taro:微信端案例豐富,百度、支付寶、H5端亦有少量案例
- uni-app:微信、App、H5三端案例豐富,官方示例已釋出到6端
- chameleon:未看到任何端案例
綜合以上資訊,本項的最終評測結論:uni-app
> taro
> chameleon
> mpvue
> wepy
、原生微信小程式
之前曾有友商掀起一番真跨端和偽跨端之爭,通過本次Demo實測,這個爭論可以蓋棺定論了。
2. 跨端框架效能如何
跨端框架基本都是compiler
+ runtime
模式,引入的runtime
是否會降低執行效能?
尤其是與原生微信小程式開發相比效能怎麼樣,這是大家普遍關心的問題。
我們依然以上述仿微博小程式為例,測試2個容易出效能問題的點:長列表載入、大量點贊元件的響應。
2.1 長列表載入
仿微博的列表是一個包含很多元件的列表,這種複雜列表對效能的壓力更大,很適合做效能測試。
從觸發上拉載入到資料更新、頁面渲染完成,需要準確計時。人眼視覺計時肯定不行,我們採用程式埋點的方式,制定瞭如下計時時機:
- 計時開始時機:互動事件觸發,框架賦值之前,如:上拉載入(onReachBottom)函式開頭
- 計時結束時機:頁面渲染完畢(微信setData回撥函式開頭)
Tips:setData
回撥函式開頭可認為是頁面渲染完成的時間,是因為微信setData
定義如下(微信規範):
欄位 | 型別 | 必填 | 描述 |
---|---|---|---|
data | Object | 是 | 這次要改變的資料 |
callback | Function | 否 | setData引起的介面更新渲染完畢後的回撥函式 |
測試方式:從頁面空列表開始,通過程式自動觸發上拉載入,每次新增20條列表,記錄單次耗時;固定間隔連續觸發 N 次上拉載入,使得頁面達到 20*N 條列表,計算這 N 次觸發上拉 -> 渲染完成
的平均耗時。
測試結果如下(表格較長,需左右滾動檢視):
列表條數 | 微信原生 | wepy | mpvue | taro | uni-app | chameleon |
---|---|---|---|---|---|---|
200 | 770 | 625 | 969 | 752 | 641 | 1261 |
400 | 876 | 781 | 4493 | 974 | 741 | 1970 |
600 | 1111 | - | - | 1250 | 910 | 2917 |
800 | 1406 | - | - | 1547 | 1113 | 4040 |
1000 | 1690 | - | - | 1878 | 1321 | 5196 |
說明:以400條微博列表為例,從頁面空列表開始,每隔1秒觸發一次上拉載入(新增20條微博),記錄單次耗時,觸發20次後停止(頁面達到400條微博),計算這20次的平均耗時,結果微信原生在這20次 觸發上拉 -> 渲染完成
的平均耗時為876毫秒,最快的uni-app
是741毫秒,最慢的mpvue是4493毫秒
大家初看這個資料,可能比較疑惑,別急,下方有詳細說明
說明1:為何 mpvue/wepy 測試資料不完整?
mpvue
、wepy
誕生之初,微信小程式尚不支援自定義元件,無法進行元件化開發;mpvue
、wepy
為解決這個問題,將使用者編寫的Vue
元件,編譯為WXML
中的模板(template),變相實現了元件化開發能力,提高程式碼複用性,這在當時的技術條件下是很棒的技術方案。
但如此方案,在複雜元件較多的頁面,會大量增加 dom 節點,甚至超出微信的 dom 節點數限制。我們在 紅米手機(Redmi 6 Pro)上實測,頁面元件超過500個時,mpvue
、wepy
實現的仿微博App就會報出如下異常,並停止渲染,故這兩個測試框架在元件較多時,測試資料不完整。這也就意味著,當頁面元件太多時,無法使用這2個框架。
dom limit exceeded please check if there's any mistake you've made
Tips:wepy
在400條列表以內,為何效能高於微信原生框架,這個跟自定義元件管理開銷及業務場景有關(wepy
編譯為模板,不涉及元件建立及管理開銷),後續對微博點贊,涉及元件資料傳遞時,微信原生框架的效能優勢就提現出來了,詳見下方測試資料。
說明2:uni-app 比微信原生框架效能更好?逆天了?
其實,在頁面上有200條記錄(200個元件)時,taro
效能資料也比微信原生框架更好。
微信原生框架耗時主要在setData
呼叫上,開發者若不單獨優化,則每次都會傳遞大量資料;而 uni-app
、taro
都在呼叫setData
之前自動做diff
計算,每次僅傳遞有變化的資料。
例如當前頁面有20條資料,觸發上拉載入時,會新載入20條資料,此時原生框架通過如下程式碼測試時,setData
會傳輸40條資料
data: {
listData: []
},
onReachBottom() { //上拉載入
let listData = this.data.listData;
listData.push(...Api.getNews());//新增資料
this.setData({
listData
}) //全量資料,傳送資料到檢視層
}
複製程式碼
開發者使用微信原生框架,完全可以自己優化,精簡傳遞資料,比如修改如下:
data: {
listData: []
},
onReachBottom() { //上拉載入
// 通過長度獲取下一次渲染的索引
let index = this.data.listData.length;
let newData = {}; //新變更資料
Api.getNews().forEach((item) => {
newData['listData[' + (index++) + ']'] = item //賦值,索引遞增
})
this.setData(newData) //增量資料,傳送資料到檢視層
}
複製程式碼
經過如上優化修改後,再次測試,微信原生框架效能資料如下:
元件數量 | 微信原生框架(優化前) | 微信原生框架(優化後) | uni-app | taro |
---|---|---|---|---|
200 | 770 | 572 | 641 | 752 |
400 | 876 | 688 | 741 | 974 |
600 | 1111 | 855 | 910 | 1250 |
800 | 1406 | 1055 | 1113 | 1547 |
1000 | 1690 | 1260 | 1321 | 1878 |
從測試結果可看出,經過開發者手動優化,微信原生框架可達到更好的效能,但 uni-app
、taro
相比微信原生,效能差距並不大。
這個結果,和web開發類似,web開發也有原生js開發、vue、react框架等情況。如果不做特殊優化,原生js寫的網頁,效能經常還不如vue、react框架的效能。
也恰恰是因為Vue
、react
框架的優秀,效能好,開發體驗好,所以原生js開發已經逐漸減少使用了。
複雜長列表載入下一頁評測結論:微信原生開發手工優化
,uni-app
>微信原生開發未手工優化
,taro
> chameleon
> wepy
> mpvue
2.2 點贊元件響應速度
長列表中的某個元件,比如點贊元件,點選時是否能及時的修改未贊和已贊狀態?是這項測試的評測點。
測試方式:
- 選中某微博,點選“點贊”按鈕,實現點贊狀態狀態切換(已贊高亮、未贊灰色),
- 點贊按鈕
onclick
函式開頭開始計時,setData
回撥函式開頭結束計時;
在紅米手機(Redmi 6 Pro)上進行多次測試,求其平均值,結果如下(表格較長,需左右滾動檢視):
列表數量 | 微信原生 | wepy | mpvue | taro | uni-app | chameleon |
---|---|---|---|---|---|---|
200 | 91 | 279 | 666 | 92 | 93 | 101 |
400 | 111 | 501 | 1507 | 125 | 107 | 145 |
600 | 144 | - | - | 152 | 148 | 178 |
800 | 176 | - | - | 214 | 181 | 236 |
1000 | 220 | - | - | 229 | 234 | 272 |
說明:也就是在列表數量為400時,微信原生開發的應用,點贊按鈕從點選到狀態變化需要111毫秒。
測試結果資料說明:
- wepy/mpvue 測試資料不完整的原因同上,在元件較多時,頁面已經不再渲染了
- 基於微信自定義元件實現元件開發的框架(uni-app/taro/chameleon),元件資料通訊效能接近於微信原生框架,遠高於基於
template
實現元件開發的框架(wepy/mpvue)效能
元件資料更新效能測評:微信原生開發
,uni-app
,taro
> chameleon
> wepy
> mpvue
綜上,本效能測試做了2個測試,長列表載入和元件狀態更新,綜合2個實驗,結論如下:
微信原生開發手工優化
,uni-app
>微信原生開發未手工優化
,taro
> chameleon
>> wepy
> mpvue
3. 學習門檻
DSL語法支援度
主流跨端框架基本都遵循React、Vue(類Vue)語法,其主要目的:複用工程師的現有技術棧,降低學習成本。此時,跨端框架對於原框架(React/Vue)語法的支援度就是一個重要的衡量標準,如果支援度較低、和原框架語法差異較大,則開發者無異於要學習一門新的框架,成本太高。
實際開發中發現,各個多端框架,都沒有完全實現vue、react在web上的所有語法:
taro
對於 JSX
的語法支援是相對完善的,其文件中描述未來版本計劃,
更多的 JSX 語法支援,1.3 之後限制生產力的語法只有只能用 map 創造迴圈元件一條
mpvue
、uni-app
框架基於 Vue.js
核心,通過修改 Vue.js
的 runtime
和 compiler
,實現了在小程式端的執行,支援絕大部分的Vue語法;uni-app
編譯到微信端曾經使用過mpvue
,但後來重寫框架,支援了更多vue語法如filter
、複雜 JavaScript
表示式等;
wepy
、chameleon
都是 類Vue
的實現,僅支援 Vue
的部分語法,開發時需要單獨學習它們的規則;
DSL語法支援評測:taro
,uni-app
> mpvue
> wepy
,chameleon
學習資料完善度
- 官方文件、搜尋系統的完備度方面:
uni-app
文件內容豐富,示例demo完備,taro
次之,其他幾個框架相對要弱一些。mpvue
文件雖少,但其概念不復雜,也沒有支援H5、App,元件、API文件都可直接看微信的文件,學習難度倒也很低。 - 教程方面:
uni-app
官方有視訊教程,不少三方專業培訓機構也錄製的uni-app
教程,包括騰訊課堂自家NEXT學院也錄製了uni-app
培訓視訊課,公開售賣;mpvue
在騰訊課堂也有三方視訊教程售賣;taro
沒有視訊教程,但官方釋出了掘金小冊;wepy
和chameleon
還沒有專業教程。
學習資料完善度評測:uni-app
> mpvue
, taro
> chameleon
> wepy
技術支援和社群活躍度
開發難免遇到問題,官方技術支援和社群活躍度很重要。
目前看,uni-app
、taro
、chameleon
都有專職人員做技術支援,uni-app
因交流群過多,還單獨引入了智慧客服機器人。
活躍的社群意味著你遇到問題有人可問、或者前人會沉澱經驗到文章裡供你搜尋。uni-app
官方有30多個交流群(其中有很多千人大群),自建論壇中有大量交流帖子;taro和mpvue有9個500人微信群;wepy官網的微信已無法新增,chameleon釋出較晚,使用者群還較少。除uni-app
外,其他框架沒有自建論壇社群。
本次評測demo開發期間,我們的同學(同時掌握vue和react),在學習研究各個多端框架時,切實感受到由於語法、學習資料、社群的差異帶來的學習門檻,吐出了很多槽。
綜合評估,本項評測結論:uni-app
> taro
> mpvue
> wepy
> chameleon
Tips:本測評忽略React、Vue兩框架自身的學習門檻
4. 工具和周邊生態
工具
所有多端框架均支援cli
模式,可以在主流前端工具中開發。
各框架基本都帶有d.ts的語法提示庫。
由於mpvue
、uni-app
、taro
直接支援vue
、react
語法,配套的ide工具鏈較豐富,著色、校驗、格式化完善,chameleon
針對部分編輯器推薦了外掛,wepy
有一些三方維護的vscode外掛。
工具屬性維度,明顯高出一截的框架是uni-app
,其出品公司同時也是HBuilder的出品公司,DCloud.io。
HBuilder/HBuilderX系列是國產開發工具,有300萬開發者使用者。
HBuilderX為uni-app
做了很多優化,故uni-app
的開發效率、易用性非其他框架可及。
當然對於不習慣HBuilderX的開發者而言,uni-app
的這個優勢無法體現。
周邊生態
一個底層框架,其周邊配套非常重要,比如ui庫、js庫、專案模板。
- wepy:出現時間久,開源專案多,佔據一定優勢。
- mpvue:釋出時間也較早,歷史積累較多。
- taro:官方提供了taro ui,github上有一些開源專案。
- uni-app:提供了外掛市場,ui庫、周邊模板豐富
- chameleon:還沒有形成周邊生態。
值得注意的是,uni-app
和mpvue
的外掛生態是互通的,都是vue外掛。所以雙方還聯合舉辦了外掛大賽。這個聯合生態的周邊豐富度,是目前各個框架中最豐富的。
順便打個廣告,歡迎有實力的同學參加 uni-app/mpvue外掛開發大賽,領取iPhone Xs Max等豐厚獎品。
綜上比較,工具和周邊生態評測結論:uni-app
,mpvue
> wepy
> taro
> chameleon
其他常見評測指標
github star:
wepy | mpvue | taro | uni-app | chameleon |
---|---|---|---|---|
17136 | 16650 | 17078 | 4728 | 4287 |
github star 數對比:wepy
> taro
> mpvue
> uni-app
> chameleon
Tips:
- star 數採集時間:2019.03.31 21:30
- star 數量和產品釋出時間有關,也和使用者使用習慣有關;除
uni-app
外,其他框架的交流互動主要是github的issus,uni-app
的開發者一般在uni-app
的問答社群中交流反饋,github頁面訪問量較低。
百度指數
百度指數代表了開發者的搜尋量和包含關鍵字的網頁數量。如下是各跨端框架近7天(2019-03-24 ~ 2019-03-30)的百度指數:
Tips:
wepy
未被百度指數收錄,說明其搜尋量和包含該關鍵字的網頁數量都不夠多。taro
和chameleon
的名稱取自於已存在的名稱,實際指代開發框架的指數應該更低。
案例
僅看釋出到微信小程式的案例,數量和質量綜合對比,wepy > mpvue > taro , uni-app > chameleon
如果看多端案例,綜合對比,uni-app > taro > mpvue > wepy > chameleon
除了uni-app
外,其他跨端框架的出品方本身為一線開發商,其內部專案會使用這些框架,經受過實戰考驗。但同時鮮有其他大開發商使用這類框架。
這裡面有面子問題,也有相容問題。很多開發商做的框架,可以滿足其自身業務需求,但對外開放後想滿足所有開發者,仍然需要投入大量工作完善產品,很多開發商主營業務不在此,並沒有這麼做。
這也是很多開源專案被稱為KPI專案的原因。
客觀講,凹凸實驗室投入如此大精力打磨taro
,讓uni-app
團隊也很驚訝和佩服。
chameleon
團隊初期投入也很大,但釋出時間還短,如果能長期投入下去,也是令人敬佩的。
uni-app
團隊本身就是專業做開發者服務的,案例很多,但創業者居多。
可以說整個多端框架市場仍處於起步期,距離讓更多開發者接受,還需要所有框架作者的共同努力。
其他補充說明
1. 開源和App側的補充說明
有的友商在評測中提到uni-app
的開源性不足問題。
需要說明下,uni-app
和其他多端框架一樣,都是前端框架,是純開源的。
除了uni-app
,其他框架的App端,或者使用expo
(一個基於react native
的封裝庫)、或者使用weex
。
做過這些開發的人都知道,原生排版引擎和web排版引擎有很多差異。而且不管react native
還是weex
,都只是渲染器,能力部分還需要開發者寫原生程式碼,這就無法跨端了。expo
比react native
強的是多封裝了一些能力,但也帶來新的限制。
uni-app
的App端,是一個真的小程式引擎,又補充了可選的weex引擎。這也是uni-app
在App端能夠提供比其他跨端框架更好相容性的原因。
而這個引擎,是另一個開源專案,叫h5p
,這個引擎是部分開源狀態。
整個業內目前還不存在一個完全開源的小程式引擎。
不過uni-app
的App端使用許可是完全免費,可以放心使用。
其實也不用好奇為什麼DCloud會有小程式引擎,因為業內第一個做小程式的並不是微信,而是DCloud。
關於App端,其實可以再寫出一篇很長的專業評測。後續uni-app
團隊會再做一篇App端與react native
、weex
、cordova
、flutter
等框架的對比。
2. 轉換和混寫
taro
提供了原生小程式轉換為taro
工程的轉換器,也支援在原生小程式裡部分頁面嵌入taro
編寫的頁面,這是taro
的特色,其他跨端框架沒有提供。這對於降低入門門檻有不少幫助。
結語
真實客觀的永遠是實驗和資料,而不是結論。不同需求的開發者,可以根據上述實驗資料,自行得出自己的選型結論。
但作為一篇完整的評測,我們也必須提供一份總結,雖然它可能加入了我們的主觀感受:
如果你想多端開發,提升效率,不想踩太多坑,uni-app
相對更完善。
如果你只開發微信小程式,不做多端,那麼使用uni-app
、微信原生開發、taro
是更優的選擇。
- 如果使用微信原生開發,需要注意手動寫優化程式碼來控制
setdata
- 如果你是
react
系,那就用taro
- 如果是
vue
系,那就用uni-app
,uni-app
在效能、周邊生態和開發效率上更有優勢
如果你主要為了微信端和H5端,那麼uni-app
和taro
都可以。可以根據自己熟悉的技術棧選擇。
如果你主要需要跨App端,uni-app
相容性更好,其他框架的App端差異過大。如果你只關心App,不關心小程式和H5,那歡迎關注我們後續的評測:uni-app
和cordova
、react native
、flutter
的深度比較。
如果你主要為了各家小程式,且不用複雜元件,那除了uni-app
和taro
,mpvue
也是不錯的選擇。mpvue
釋出2.0版本後,搜尋指數明顯爬升,希望能持續更新,迎來二次繁榮。
chameleon
釋出不久,提供的元件和API還很少,但其未來的規劃比較令人期待,值得關注。
這篇評測寫完後,小編有點惴惴不安。
一方面本評測不太溫和,容易得罪人。但我們相信,這樣的評測,會激起所有跨端框架從業者的鬥志,讓大家投入更多去完善產品,這對整個產業、對前端開發者,是大好事。
另一方面,讀者可能會以為現階段的uni-app
很完美,其實我們深知uni-app
還有很多需要完善的地方。uni-app
團隊也將持續投入心血,為中國的前端開發者造福!
如有讀者認為本文中任何評測失真,歡迎在這裡報issus。