小程序原生开发有不少槽点:
- 原生wxml开发对Node、预编译器、webpack支持不好,影响开发效率和工程构建流程。所以大公司都会用框架开发
- 微信定义的这套语法,wxml、wxs,以及wx:if等语法,私有化太强。不如正经学vue,学会了全端通用,而不是只为微信小程序
- vue生态里有太多周边工具,可以提高开发效率,比如ide、校验器、三方库。。。而微信的开发者工具和专业编辑器相比实在不好用,个性化设置也非常少
作为前端工程师,除了微信小程序,还要开发web、其他小程序甚至App,人们不喜欢来回切换开发工具和变更语法思考方式。
uni-app自然可以解决这些问题,但开发者又经常有些顾虑:
- 怕使用uni-app后,微信小程序里有的功能无法实现,受制于uni-app的更新
- 怕性能不如原生WXML
- 怕框架不成熟,跳到坑里
- 担心社区生态不完善
本文从开发者关心的功能、性能、学习门槛、开发体验、生态、可扩展性等维度,逐个分析对比,给予说明。
1.功能实现
开发者最常问的问题:如果小程序迭代升级,新增了一批API,但?uni-app ?框架未及时更新,该怎么办?
其实这是误解,?uni-app ?不限制底层API 调用;在小程序端,?uni-app ?支持直接编写微信原生代码。
类比传统web开发,如果vue、react等框架的使用,造成开发者无法操作浏览器提供的所有api,那这样的框架肯定是不成熟的。小程序开发也一样,?uni-app ?框架中,同样可调用微信提供的所有原生代码。
故如果存在某些API(平台特有或新增API),?uni-app ?尚未封装,开发者可直接在?uni-app 中编写微信原生API,即wx.开头的各种API。
举个例子,目前?uni-app ?虽然尚未封装跨平台的广告(ad)组件,但开发者在小程序端依然可以使用微信?<ad> ?组件来展现广告,代码示例如下:
<view>
<view class="title">微信官方banner广告</view style="min-height: 50px;">
<ad unit-id="adunit-01b7axxxbf53d74e"></ad>
</"title">微信官方视频广告</"adunit-9f340xxx64533" ad-type="video" ad-theme="white"></view>
</view>
复制代码
小程序端运行效果如下:
![](http://img50.lidatong.com.cn//uploads/allimg/c20201214/29d586149a66c701758e079a1ee2d128.gif)
包括微信小程序自定义组件、WXS、云开发这些复杂用法,在uni-app里一样全面支持。
所以,结论是:使用?uni-app ?框架开发,在功能上和原生小程序开发没有区别,不会有任何限制。
2. 性能体验
开发者常问的第二个问题:三方框架,内部大多做了层层封装,这些封装是否会增加运行负载,导致性能下降?
同样是多虑了,?uni-app ?不会导致性能下载,甚至对很多环节做了自动优化,很多场景下性能体验比微信原生开发更好。
类似使用vue.js开发web,不但不会造成性能比原生js差,反而由于虚拟dom和差量更新技术的运用,在大多数场景下,比开发者手动写代码操作dom的性能还好。
小程序中需要频繁的写setData代码来更新数据,这里很重要的就是差量数据更新。如果不做差量,代码性能不好,如果每处逻辑都判断差量数据更新,那代码写起来太麻烦了。
使用?uni-app ?,底层自动差量数据更新,简单而高性能。
我们从优化理论、实测数据两个维度来仔细说明。
2.1 理论:框架优化方案
为提高性能体验,小程序从架构设计层面做了很多工作:
- 逻辑层、视图层分离,避免JS运算阻塞视图渲染
- 单独定义组件标签(wxml),减少DOM复杂度
- 精简样式(wxss),提升渲染性能
- 复杂组件原生化(video/map等),解决web组件的功能/体验缺失
通过这些规范约束,大幅提升了小程序的整体性能体验,但依然存在不少性能坑点,其中以?setData ?最为频繁普遍。
这里引用微信官方的描述,简单介绍一下?setData ?背后的工作原理:
小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。
为简化开发,微信将?evaluateJavascript ?调用封装成了?setData ?JS方法,实现视图层和逻辑层的数据传输,数据流示意图如下:
![](http://img50.lidatong.com.cn//uploads/allimg/c20201214/7912618b9b461b0081d9ba42a31782e2.gif)
setData ?的执行会受到很多因素的影响,?setData ?每次传递数据量过大或频繁被调用(?见微信官方介绍?),都可能引发性能体验问题。
幸运的是,?uni-app ?在这两个方面都有优化。
2.1.1 减少 setData 传递数据量
假设当前页面有一个列表(初始值为?a,b,c,d ?),现在要向列表后追加4个新列表项(?e,f,g,h ?),我们分别以微信原生、uni-app 两种模式编写代码。
小程序原生代码:
page({
data:{
list:['a','b',0);">'c',0);">'d']
},change:function(){
let newData = ['e',0);">'f',0);">'g',0);">'h'];
this.data.list.push(...newData);
this.setData({
list:data.list
})
}
})
复制代码
如上微信原生代码,?change ?方法执行时,会将?list ?中的?setData ?全部传输过去。
uni-app 代码:
export default{
data(){
return {
list:['d']
}
},methods:{
change:function(){
let newData = ['h'];
this.list.push(...newData)
}
}
}
复制代码
如上?uni-app ?代码,?change ?方法执行时,仅会将?setData ?传输量的极简化。
uni-app?借鉴了 westore JSON Diff库,在调用?setData ?之前,会先比对历史数据,精确、高效计算出有变化的差量数据,然后再调用?setData ?,仅传输变化的数据,这样就实现 setData 传递数据量的最小化,大幅提高通讯性能。
Tips:也许有些同学对传递数据从??4个列表项,不以为然,但我们提醒,不要小看这个机制,上述只是demo示例。
- 在实际列表场景中,每个列表项可能包含缩略图、标题、摘要、时间等各种信息,每个列表项数据都会更大(假设为1k);
- 假设当前页面有20个列表项,连续上拉4次后,页面变成100条记录;如果再次上拉,页面变成120条记录时,情况会有不同
- 上述微信原生的方式,将120条记录数据(120k)全部传输过去
- 上述 uni-app 模式,仅会将新增的20条(101 ~ 120)记录数据(20k)传输过去,数据量是原生方式的1/6!
- 当页面列表项数据越多,这个差别就越大,页面有200条记录时,uni-app传递数据量会变成微信原生数据传递量的1/10!
2.1.2 减少 setData 调用频次
假设我们有更改多个变量值的需求,我们分别以微信原生、uni-app 两种模式编写代码。
小程序原生代码:
change:function(){
this.setData({a:1});
b:2});
c:3});
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 机制。
2.2 实测:性能对比数据
有了如上的理论分析,我们接着进行真机实测,用数据来对比。
测试模型如下:
开发内容:开发一个仿微博小程序首页的复杂长列表,支持下拉刷新、上拉翻页、点赞。?仿微博的列表是一个包含很多组件的列表,这种复杂列表对性能的压力更大,很适合做性能测试。
-
界面如下:
![](http://img50.lidatong.com.cn//uploads/allimg/c20201214/e61598c65cc932c377d7b36d932c66ee.gif)
开发版本:使用微信原生、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进程、清空内存,保证测试机环境基本一致;每次从本地读取静态数据,屏蔽网络差异。
从触发上拉加载到数据更新、页面渲染完成,需要准确计时。人眼视觉计时肯定不行,我们采用程序埋点的方式,制定了如下计时时机:
- 计时开始时机:交互事件触发,框架赋值之前,如:上拉加载(onReachBottom)函数开头
- 计时结束时机:页面渲染完毕(微信setData回调函数开头)
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 ?计算,每次仅传递变动的数据。
开发者使用微信原生框架,完全可以自己优化,精简传递数据,比如修改如下:
+ (index++) + ']'] = item
})
this.setData(newData)
}
复制代码
经过如上优化修改后,再次测试,微信原生框架性能数据如下:
组件数量 |
微信原生框架(优化前) |
微信原生框架(优化后) |
572
| 688 |
855 |
1055 |
1260 |
uni-app 不会增加小程序运行负载,不会拉低运行性能
uni-app 自动处理了很多性能优化点,对不懂性能调优或不熟悉小程序架构设计的开发者,更友好,更省心
3.社区生态
3.1 周边轮子
小程序是脱离web自造生态,很多web生态中轮子无法使用。
微信小程序还是有周边生态的,而其他几家小程序平台的生态基本没建起来。
uni-app?的周边生态非常丰富,在插件市场有近800个插件,详见?ext.dcloud.net.cn?。
首先?uni-app ?兼容小程序的生态,各种自定义组件均可直接引入使用。在此基础上,?uni-app 的插件市场,有更多vue组件,同时可跨多端使用,并且性能优秀。
这使得?uni-app ?的生态成为最丰富的小程序开发生态。
比如富文本解析、图表等组件,?uni-app ?的插件性能均超过了wxparse、wx-echart等微信小程序组件。
如果开发者需要丰富和高性能的组件,更应该使用?uni-app ?,而不是原生小程序开发。
3.2 活跃的QQ/微信群和论坛
uni-app?官方有 70 个开发者QQ/微信交流群(大多2千人群,近10万开发者),三方群更多。
问答社区?,每天有数百篇帖子。活跃度与微信小程序官方论坛相同,远超过其他小程序官方论坛。
uni-app?三方培训活跃,腾讯课堂官方都为uni-app制作了课程,各种培训网站到处可见免费或收费的uni-app培训视频教程。
4.学习门槛、开发体验
首先微信原生的开发语法,既像?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 ?有较大差距,主要体现在:
- 更为强大的组件化开发能力:vue的组件开发比小程序自定义组件开发的体验要好很多
- 应用状态管理:uni-app支持vuex
- 使用 Sass 等 CSS 预处理器
- 完整的 ES Next 语法支持
- 自定义构建策略
开发工具维度,差距更大:
- 微信开发者工具被吐槽无数
-
uni-app ?的出品公司,同时也是HBuilder的出品公司,?DCloud.io?。HBuilder/HBuilderX系列是四大主流前端开发工具(可对比?百度指数?),其为?uni-app ?做了很多优化,故?uni-app 的开发效率、易用性非微信原生开发可及。
这里可以输出一个结论:如果你需要工程化能力,那就直接忘了微信原生开发吧。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|
|