上周, Taro 团队发布了一篇《 小程序 多端框架全面测评》, 让开发者对业界主流的跨端框架, 有了初步认识. 感谢 Taro 团队的付出.
不过横评这件事, 要想做完善, 其实非常花费时间. 不是只看文档就行, 它需要:
真实的动手写多个平台的测试 demo, 比较各个平台的功能, 性能, 它们的实际情况到底是不是如文档宣传的那样?
真实的学习每个框架, 了解它们的学习曲线, 在实际开发中遇到问题时, 感受它们的文档, 教程, 社区生态和技服能力到底怎么样?
我们 http://www.yidonghua.com/uni-app 团队投入一周完成了这个深度评测, 下面我们就分享下, 实际开发不同框架的测试例遇到的问题, 和最终的测试结果.
评测实验介绍
开发内容: 开发一个仿微博 小程序 首页的复杂长列表, 支持下拉刷新, 上拉翻页, 点赞.
界面如下:
开发版本: 一共开发了 6 个版本, 包括微信原生版, wepy 版, mpvue 版, taro 版, http://www.yidonghua.com/uni-app 版, chameleon 版(以这些产品发布时间排序, 下同), 按照官网指引通过 cli 方式默认安装(应该是最新稳定版).
测试代码开源( GitHub 仓库地址: https://github.com/dcloudio/test-framework https://github.com/dcloudio/test-framework ),
Tips: 若有同学觉得测试代码写法欠妥, 欢迎提交 PR 或 Issus https://github.com/dcloudio/test-framework/issues
测试机型: 红米 Redmi 6 Pro,MIUI 10.2.2.0 稳定版(最新版), 微信版本 7.0.3(最新版)
测试环境: 每个框架开始测试前, 杀掉各 App 进程, 清空内存, 保证测试机环境基本一致; 每次从本地读取静态数据, 屏蔽网络差异.
测试维度:
跨端支持度如何?
性能如何?
学习门槛
工具与周边生态
1. 跨端支持度如何
开发一次, 到处运行, 是每个程序员的梦想. 但现实往往变成开发一次, 到处调错.
各个待评测框架, 是否真得如宣传的那样, 一次开发, 多端发布?
我们将上述 仿微博 App https://github.com/dcloudio/test-framework 依次发布到各平台, 验证每个框架在各端的兼容性, 结果如下:
平台 | 微信原生 | wepy | mpvue | taro | uni-app | chameleon |
---|---|---|---|---|---|---|
微信小程序 | :o:️ | :o:️ | :o:️ | :o:️ | :o:️ | :o:️ |
支付宝小程序 | :x: | :x: | :o:️ | :o:️ | :o:️ | :x: |
百度小程序 | :x: | :x: | :o:️ | :o:️ | :o:️ | :x: |
头条小程序 | :x: | :x: | :o:️ | :o:️ | :o:️ | :x: |
H5 端 | :x: | :x: | :x: | 上拉加载 / 下拉刷新失效 | :o:️ | 上拉加载 / 下拉刷新失效 |
App 端 | :x: | :x: | :x: | 上拉加载失效 | :o:️ | 列表无法滚动,无法测试上拉加载 / 下拉刷新 |
测试结果说明:
:o: 表示支持且功能正常,:x: 表示不支持, 其它则表示支持但存在部分 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
- uni-App
- chameleon
跨端框架, 一方面要考虑框架提供的通用 API 跨端支持, 同时还要考虑不同端的特色差异如何兼容. 毕竟每个端都会有自己的特色, 不可能完全一致.
- taro
- uni-App
- chameleon
跨端框架, 还涉及一个 ui 框架的跨端问题, 评测结果如下:
taro : 官方提供了 taro ui , 支持小程序(微信 / 支付宝 / 百度),H5 平台, 不支持 App, 详见 https://taro-ui.aotu.io/#/
uni-App : 官方提供了 uni ui , 可全端运行; uni-App 还有一个插件市场, 里面有很多三方 ui 组件, 详见 https://ext.dcloud.net.cn/
chameleon : 官方提供了 cml-ui 扩展组件库, 可全端运行, 但组件数量略少, 详见 https://cmljs.org/doc/component/expand/expand.html
最后补充跨端案例:
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 毫秒.
测试结果数据说明:
template
组件数据更新性能测评: 微信原生开发 , 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 https://dcloud.io/ .
HBuilder/HBuilderX 系列是国产开发工具, 有 300 万开发者用户.
HBuilderX 为 uni-App 做了很多优化, 故 uni-App 的开发效率, 易用性非其他框架可及.
当然对于不习惯 HBuilderX 的开发者而言, uni-App 的这个优势无法体现.
周边生态
一个底层框架, 其周边配套非常重要, 比如 ui 库, JS 库, 项目模板.
wepy: 出现时间久, 开源项目多, 占据一定优势.
mpvue: 发布时间也较早, 历史积累较多.
taro: 官方提供了 taro ui,GitHub 上有一些开源项目.
uni-App: 提供了 插件市场 https://ext.dcloud.net.cn/ ,ui 库, 周边模板丰富
chameleon: 还没有形成周边生态.
值得注意的是, uni-App 和 mpvue 的插件生态是互通的, 都是 vue 插件. 所以双方还联合举办了插件大赛. 这个联合生态的周边丰富度, 是目前各个框架中最丰富的.
顺便打个广告, 欢迎有实力的同学参加 uni-App/mpvue 插件开发大赛 http://ask.dcloud.net.cn/article/35700 , 领取 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 https://github.com/dcloudio/test-framework .
移动信息化交流 QQ 群: 一号群: 211029692 二号群: 344692795 CIO 交流群: 316076815(需认证)
来源: http://www.tuicool.com/articles/2U3QbqR