小程序原生開發有很多槽點:javascript
做爲前端工程師,除了微信小程序,還要開發web、其餘小程序甚至App,人們不喜歡來回切換開發工具和變動語法思考方式。html
uni-app天然能夠解決這些問題,但開發者又常常有些顧慮:前端
本文從開發者關心的功能、性能、學習門檻、開發體驗、生態、可擴展性等維度,逐個分析對比,給予說明。vue
開發者最常問的問題:若是小程序迭代升級,新增了一批API,但uni-app
框架未及時更新,該怎麼辦?java
其實這是誤解,uni-app
不限制底層API 調用;在小程序端,uni-app
支持直接編寫微信原生代碼。node
類比傳統web開發,若是vue、react等框架的使用,形成開發者沒法操做瀏覽器提供的全部api,那這樣的框架確定是不成熟的。小程序開發也同樣,uni-app
框架中,一樣可調用微信提供的全部原生代碼。react
故若是存在某些API(平臺特有或新增API),uni-app
還沒有封裝,開發者可直接在uni-app
中編寫微信原生API,即wx.開頭的各類API。webpack
舉個例子,目前uni-app
雖然還沒有封裝跨平臺的廣告(ad)組件,但開發者在小程序端依然可使用微信<ad>
組件來展示廣告,代碼示例以下:git
<view> <view class="title">微信官方banner廣告</view> <view style="min-height: 50px;"> <!-- uni-app還沒有封裝,但可直接使用微信原生的ad組件--> <ad unit-id="adunit-01b7axxxbf53d74e"></ad> </view> <view class="title">微信官方視頻廣告</view> <view style="min-height: 50px;"> <!-- uni-app還沒有封裝,但可直接使用微信原生的ad組件--> <ad unit-id="adunit-9f340xxx64533" ad-type="video" ad-theme="white"></ad> </view> </view>
小程序端運行效果以下:
程序員
包括微信小程序自定義組件、WXS、雲開發這些複雜用法,在uni-app裏同樣全面支持。
因此,結論是:使用uni-app
框架開發,在功能上和原生小程序開發沒有區別,不會有任何限制。
開發者常問的第二個問題:三方框架,內部大多作了層層封裝,這些封裝是否會增長運行負載,致使性能降低?
一樣是多慮了,uni-app
不會致使性能下載,甚至對不少環節作了自動優化,不少場景下性能體驗比微信原生開發更好。
相似使用vue.js開發web,不但不會形成性能比原生js差,反而因爲虛擬dom和差量更新技術的運用,在大多數場景下,比開發者手動寫代碼操做dom的性能還好。
小程序中須要頻繁的寫setData代碼來更新數據,這裏很重要的就是差量數據更新。若是不作差量,代碼性能很差,若是每處邏輯都判斷差量數據更新,那代碼寫起來太麻煩了。
使用uni-app
,底層自動差量數據更新,簡單而高性能。
咱們從優化理論、實測數據兩個維度來仔細說明。
爲提升性能體驗,小程序從架構設計層面作了不少工做:
經過這些規範約束,大幅提高了小程序的總體性能體驗,但依然存在很多性能坑點,其中以setData
最爲頻繁廣泛。
這裏引用微信官方的描述,簡單介紹一下setData
背後的工做原理:
小程序的視圖層目前使用 WebView 做爲渲染載體,而邏輯層是由獨立的 JavascriptCore 做爲運行環境。在架構上,WebView 和 JavascriptCore 都是獨立的模塊,並不具有數據直接共享的通道。當前,視圖層和邏輯層的數據傳輸,實際上經過兩邊提供的 evaluateJavascript 所實現。
爲簡化開發,微信將evaluateJavascript
調用封裝成了setData
JS方法,實現視圖層和邏輯層的數據傳輸,數據流示意圖以下:
setData
的執行會受到不少因素的影響,setData
每次傳遞數據量過大或頻繁被調用(見微信官方介紹),均可能引起性能體驗問題。
幸運的是,uni-app
在這兩個方面都有優化。
假設當前頁面有一個列表(初始值爲a,b,c,d
),如今要向列表後追加4個新列表項(e,f,g,h
),咱們分別以微信原生、uni-app 兩種模式編寫代碼。
小程序原生代碼:
page({ data:{ list:['a','b','c','d'] }, change:function(){ let newData = ['e','f','g','h']; this.data.list.push(...newData); this.setData({ list:this.data.list }) } })
如上微信原生代碼,change
方法執行時,會將list
中的a,b,c,d,e,f,g,h
8個列表項經過setData
所有傳輸過去。
uni-app 代碼:
export default{ data(){ return { list:['a','b','c','d'] } }, methods:{ change:function(){ let newData = ['e','f','g','h']; this.list.push(...newData) } } }
如上uni-app
代碼,change
方法執行時,僅會將list
中的e,f,g,h
4個新增列表項傳輸過去,實現了setData
傳輸量的極簡化。
uni-app
借鑑了 westore JSON Diff庫,在調用setData
以前,會先比對歷史數據,精確、高效計算出有變化的差量數據,而後再調用setData
,僅傳輸變化的數據,這樣就實現 setData 傳遞數據量的最小化,大幅提升通信性能。
Tips:也許有些同窗對傳遞數據從a,b,c,d,e,f,g,h
8個列表項優化爲e,f,g,h
4個列表項,不覺得然,但咱們提醒,不要小看這個機制,上述只是demo示例。
假設咱們有更改多個變量值的需求,咱們分別以微信原生、uni-app 兩種模式編寫代碼。
小程序原生代碼:
change:function(){ this.setData({a:1}); this.setData({b:2}); this.setData({c:3}); this.setData({d:4}); }
如上四次調用setData
,就會引起4次邏輯層、視圖層數據通信
uni-app 代碼:
change:function(){ this.a = 1; this.b = 2; this.c = 3; this.d = 4; }
如上uni-app
的代碼,最後會被合併成{"a":1,"b":2,"c":3,"d":4}
一條數據,而後僅調用一次setData
完成全部數據傳遞,大幅下降了setData
的調用頻次。
uni-app
之因此有這樣的優點,是由於 uni-app 基於 Vue Runtime 深度定製實現,並藉助了 Vue 的 nextTick 機制。
有了如上的理論分析,咱們接着進行真機實測,用數據來對比。
測試模型以下:
仿微博的列表是一個包含不少組件的列表,這種複雜列表對性能的壓力更大,很適合作性能測試。
cli
方式默認安裝。Tips:如有同窗以爲測試代碼寫法欠妥,歡迎提交 PR 或 Issus,本項目下還有其它框架的測試代碼,開發者可忽略
從觸發上拉加載到數據更新、頁面渲染完成,須要準確計時。人眼視覺計時確定不行,咱們採用程序埋點的方式,制定了以下計時時機:
Tips:setData
回調函數開頭可認爲是頁面渲染完成的時間,是由於微信setData
定義以下(微信規範):
字段 | 類型 | 必填 | 描述 |
---|---|---|---|
data | Object | 是 | 此次要改變的數據 |
callback | Function | 否 | setData引發的界面更新渲染完畢後的回調函數 |
測試方式:從頁面空列表開始,經過程序自動觸發上拉加載,每次新增20條列表,記錄單次耗時;固定間隔連續觸發 N 次上拉加載,使得頁面達到 20*N 條列表,計算這 N 次觸發上拉到渲染完成的平均耗時。
測試結果以下:
列表條數 | 微信原生 | uni-app |
---|---|---|
200 | 770 | 641 |
400 | 876 | 741 |
600 | 1111 | 910 |
800 | 1406 | 1113 |
1000 | 1690 | 1321 |
說明:以400條微博列表爲例,從頁面空列表開始,每隔1秒觸發一次上拉加載(新增20條微博),記錄單次耗時,觸發20次後中止(頁面達到400條微博),計算這20次的平均耗時,結果微信原生在這20次 觸發上拉 -> 渲染完成
的平均耗時爲876毫秒,uni-app
是741毫秒。
這個數據,可能違反了不少人的直覺,uni-app 的性能居然比微信原生還好!
沒必要疑惑,這就是上面理論分析章節中,減小setData
傳遞數據量優化方案的結果;微信原生每次傳遞全量數據,而uni-app
在調用setData
以前會自動作diff
計算,每次僅傳遞變更的數據。
開發者使用微信原生框架,徹底能夠本身優化,精簡傳遞數據,好比修改以下:
data: { listData: [] }, onReachBottom() { //上拉加載 // 經過長度獲取下一次渲染的索引 let index = this.data.listData.length; let newData = {}; //新變動數據 Api.getNews().forEach((item) => { newData['listData[' + (index++) + ']'] = item //賦值,索引遞增 }) this.setData(newData) //增量數據,發送數據到視圖層 }
通過如上優化修改後,再次測試,微信原生框架性能數據以下:
組件數量 | 微信原生框架(優化前) | 微信原生框架(優化後) | uni-app |
---|---|---|---|
200 | 770 | 572 | 641 |
400 | 876 | 688 | 741 |
600 | 1111 | 855 | 910 |
800 | 1406 | 1055 | 1113 |
1000 | 1690 | 1260 | 1321 |
從測試結果可看出,通過開發者手動優化,微信原生框架可達到更好的性能,但 uni-app
相比微信原生,性能差距並不大。
但原生開發須要開發者熟悉小程序通信機制,有意識的去編寫代碼,精簡數據;uni-app自動處理,天然是更省心。
這個結果,和web開發相似,web開發也有原生js開發、vue、react框架等狀況。若是不作特殊優化,原生js寫的網頁,性能常常還不如vue、react框架的性能。
也偏偏是由於Vue
、react
框架的優秀,性能好,開發體驗好,因此原生js開發已經逐漸減小使用了。
經過本章節性能優化的理論分析及數據實測,咱們能夠輸出這麼個結論:
小程序是脫離web自造生態,不少web生態中輪子沒法使用。
微信小程序仍是有周邊生態的,而其餘幾家小程序平臺的生態基本沒建起來。
uni-app
的周邊生態很是豐富,在插件市場有近800個插件,詳見 ext.dcloud.net.cn。
首先uni-app
兼容小程序的生態,各類自定義組件都可直接引入使用。在此基礎上,uni-app
的插件市場,有更多vue組件,同時可跨多端使用,而且性能優秀。
這使得uni-app
的生態成爲最豐富的小程序開發生態。
好比富文本解析、圖表等組件,uni-app
的插件性能均超過了wxparse、wx-echart等微信小程序組件。
若是開發者須要豐富和高性能的組件,更應該使用uni-app
,而不是原生小程序開發。
uni-app
官方有 70 個開發者QQ/微信交流羣(大多2千人羣,近10萬開發者),三方羣更多。
問答社區,天天有數百篇帖子。活躍度與微信小程序官方論壇相同,遠超過其餘小程序官方論壇。
uni-app
三方培訓活躍,騰訊課堂官方都爲uni-app製做了課程,各類培訓網站處處可見免費或收費的uni-app培訓視頻教程。
首先微信原生的開發語法,既像React
,又像Vue
,有點不三不四,對於開發者來講,等於又要學習一套新的語法,大幅提高了學習成本,這一直被你們所詬病。
uni-app
則對開發者更爲友好,簡單來講是 vue的語法 + 小程序的api。
它遵循Vue.js
語法規範,組件和API遵循微信小程序命名
,這些都屬於通用技術棧,學習它們是前端必備技能,uni-app
沒有太多額外學習成本。
有必定 Vue.js 和微信小程序開發經驗的開發者可快速上手 uni-app
。
沒學過vue的同窗,也不用掌握vue的所有,只需瞭解vue基礎語法、數據綁定、列表渲染、組件等,其餘如路由、loader、cli、node.js、webpack並不須要學。
由於HBuilderX工具搭配uni-app
能夠免終端開發,可視化建立項目、可視化安裝組件和擴展編譯器,也就是uni-app
的學習門檻,比web開發的vue.js還低。
開發體驗層面,微信原生開發相比uni-app
有較大差距,主要體如今:
開發工具維度,差距更大:
uni-app
的出品公司,同時也是HBuilder的出品公司,DCloud.io。HBuilder/HBuilderX系列是四大主流前端開發工具(可對比百度指數),其爲uni-app
作了不少優化,故uni-app
的開發效率、易用性非微信原生開發可及。這裏能夠輸出一個結論:若是你須要工程化能力,那就直接忘了微信原生開發吧。
雖然當前產品僅要求發佈到微信小程序,但如有一天,老闆和外來的一個和尚喝完咖啡,轉身就要求覆蓋阿里、百度、字節跳動等各家小程序平臺,此時程序員該怎麼辦?
難道真的每一個平臺處處搬磚嗎?
此時,uni-ap
的跨端功能將成爲程序員的自救神器,基於uni-app
開發的小程序,無需修改,便可同時發佈到多家小程序,甚至App、H5平臺。這不是夢想,而是現實。你們可依次掃描以下8個二維碼,親自體驗最全面的跨平臺效果!。
uni-app | 微信 | |
---|---|---|
功能 | 相同 | 相同 |
性能 | 常規場景更優 | 須要本身編寫複雜代碼才能提升性能 |
社區生態 | 豐富,更多高性能組件 | 豐富 |
開發體驗 | 純vue體驗,高效、統一;工程化能力強 | 語法私有化;工程化能力弱 |
多端能力 | 同時支持H五、多家小程序、跨平臺App | 只能用於微信小程序 |
結論:只開發微信小程序,也應該使用uni-app