上周,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 团队也将持续投入心血,为中国的前端开发者造福!
如有读者认为本文中任何评测失真,欢迎在这里报 issues。