小程序原生开发有很多槽点: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 机制。
有了如上的理论分析,咱们接着进行真机实测,用数据来对比。
测试模型以下:
开发内容:开发一个仿微博小程序首页的复杂长列表,支持下拉刷新、上拉翻页、点赞。仿微博的列表是一个包含不少组件的列表,这种复杂列表对性能的压力更大,很适合作性能测试。
界面以下:
开发版本:使用微信原生、uni-app分别开发两套代码,uni-app使用cli
方式默认安装。
测试代码开源(Github仓库地址:https://github.com/dcloudio/test-framework), Tips:如有同窗以为测试代码写法欠妥,欢迎提交 PR 或 Issus,本项目下还有其它框架的测试代码,开发者可忽略
测试机型:红米 Redmi 6 Pro、MIUI 10.2.2.0 稳定版(最新版)、微信版本 7.0.3(最新版)
测试环境:每一个框架开始测试前,杀掉各App进程、清空内存,保证测试机环境基本一致;每次从本地读取静态数据,屏蔽网络差别。
从触发上拉加载到数据更新、页面渲染完成,须要准确计时。人眼视觉计时确定不行,咱们采用程序埋点的方式,制定了以下计时时机:
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