原生开发对 Node、预编译器、webpack 支持不好,影响开发效率和工程构建流程。
vue/react 生态里有太多周边工具,可以提高开发效率,比如 ide、校验器、三方库……
同时,开发者对三方框架,又总是有各种顾虑:
怕性能不如原生。
怕有些功能框架实现不了,只能用原生。
怕框架不稳定,跳到坑里。
以及诸多三方框架,到底该用哪个。
面对如此纠结的场景,不少热心开发者发布评测文章分享经验,但感觉众说纷纭,过期信息太多。缺少一份非常专业的、深度的,或者按如今流行的话来讲,“硬核的”评测报告。
做评测报告这件事,不同于泛泛经验分享,其实非常花费时间。它需要:
你必须成为每一个框架的专业使用人员,而不是浅浅的了解一下这些框架。
真实的动手写多个平台的测试例,比较各个平台的功能、性能,了解他们的社区情况、技术服务情况。
你要有长期跟踪和更新报告的能力,避免半年后沦为过期信息。
换言之:评测要想真,功夫得做深!
uni-app团队花费 2 个周时间完成本报告,并坚持每个季度更新一次本评测报告。目前更新时间为 2019 年 5 月。
面向用户、面向开发者维度,具体包括:
用户:提供完整的业务实现,并保证高性能体验。
开发者:平缓的学习曲线、现代开发体验(工程化)、高效的社区支持、活跃的开发迭代、多端复用。
1. 用户
1.1 功能实现
软件开发,首要目标是向用户提供完整、闭环的业务功能。
实际上就像 web 开发的 vue、react 一样,浏览器出了一个新 API,并不会涉及 vue、react 的升级。本评测里的所有框架,都不会限制开发者调用底层能力。这里详细解释下原因:
注:以上顺序,按各个框架的诞生顺序排序,下同。
相关链接:
条件编译:
https://uniapp.dcloud.io/platform
然而有差别的,是性能体验。
1.2 性能体验
为客观的进行对比,我们特意搭建了一个测试模型,详细如下:
界面如下:
https://github.com/dcloudio/test-framework/issues
测试环境:每个框架开始测试前,杀掉各 App 进程、清空内存,保证测试机环境基本一致;每次从本地读取静态数据,屏蔽网络差异。
1.2.1 长列表加载
仿微博的列表是一个包含很多组件的列表,这种复杂列表对性能的压力更大,很适合做性能测试。
从触发上拉加载到数据更新、页面渲染完成,需要准确计时。人眼视觉计时肯定不行,我们采用程序埋点的方式,制定了如下计时时机:
计时开始时机:交互事件触发,框架赋值之前,如:上拉加载(onReachBottom)函数开头
相关链接:
https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html?search-key=Page.prototype.setData
测试方式:从页面空列表开始,通过程序自动触发上拉加载,每次新增 20 条列表,记录单次耗时;固定间隔连续触发 N 次上拉加载,使得页面达到 20*N 条列表,计算这 N 次触发上拉到渲染完成的平均耗时。
测试结果如下:
大家初看这个数据,可能比较疑惑,别急,下方有详细说明
说明 1:为何 mpvue/wepy 测试数据不完整?
dom limit exceeded please check if there’s any mistake you’ve made
相关链接:
自定义组件:
https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
模板(template):
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html
CHANGELOG:https://tencent.github.io/wepy/document.html#/changelog
例如当前页面有 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) // 增量数据,发送数据到视图层}
这个结果,和 web 开发类似,web 开发也有原生 js 开发、vue、react 框架等情况。如果不做特殊优化,原生 js 写的网页,性能经常还不如 vue、react 框架的性能。
也恰恰是因为Vue、react框架的优秀,性能好,开发体验好,所以原生 js 开发已经逐渐减少使用了。
Tips:有人以为 uni-app 和 mpvue 是一样的,早期 uni-app 确实使用过 mpvue,但后来因为性能和 vue 语法支持度问题已经重新开发了。
测试方式:
在红米手机(Redmi 6 Pro)上进行多次测试,求其平均值,结果如下:
测试结果数据说明:
wepy/mpvue 测试数据不完整的原因同上,在组件较多时,页面已经不再渲染了。
综上,本性能测试做了 2 个测试,长列表加载和组件状态更新,综合 2 个实验,结论如下:
2. 开发者
在满足用户业务需求的前提下,我们谈谈开发者的需求,从如下几个维度比较:
平缓的学习曲线:简单易学,最好能复用现有技术栈,丰富的学习资料。
高效的开发体验:现代前端开发流程、工程化支持。
高效的社区支持:遇到问题,可很快的寻求到帮助。
活跃的开发迭代:框架处于积极更新升级状态,无需担心停更。
2.1 平缓的学习曲线
2.1.1 DSL 语法支持
选择开发团队熟悉的、能快速上手的 DSL,是团队框架选型的基本点。
其它开发框架基本都遵循 React、Vue(类 Vue)语法,其主要目的:复用工程师的现有技术栈,降低学习成本。此时,框架对于原框架(React/Vue)语法的支持度就是一个重要的衡量标准,如果支持度较低、和原框架语法差异较大,则开发者无异于要学习一门新的框架,成本太高。
实际开发中发现,各个开发框架,都没有完全实现Vue、React在 web 上的所有语法:
taro 对于 JSX 的语法支持度,也达到了绝大多数都支持的完善程度。
2.1.2 学习资料完善度
官方文档、问题搜索、示例 demo 的完备度方面:
uni-app:基础文档和各种使用专题内容丰富,问题搜索效果较好,示例 demo 功能完备,并发布为 7 端上线。详见:https://uniapp.dcloud.io/
教学课程方面:
2.2 现代前端开发体验
框架开发提供了更强大的组件化能力。
框架开发提供了应用状态管理(类 Vuex/Redux/Mobx 等)。
框架开发能灵活支持各种 Sass 等 预处理器。
框架开发可提供完整的 ES Next 语法支持。
框架开发方便自定义构建策略。
由于mpvue、uni-app、taro直接支持vue、react语法,配套的 ide 工具链较丰富,着色、校验、格式化完善;wepy要弱一些,有部分三方维护的 vscode 插件。
好的开发工具,绝对可以大幅提升开发体验,这个维度上,明显高出一截的框架是uni-app,其出品公司同时也是 HBuilder 的出品公司,DCloud.io(https://dcloud.io/)。HBuilder 是四大主流前端开发工具(可对比百度指数,详见下方链接),其为uni-app做了很多优化,故uni-app的开发效率、易用性非其他框架可及。
相关链接:
对比百度指数:http://zhishu.baidu.com/v2/main/index.html#/trend/vscode?words=vscode,hbuilder,webstorm,sublime
2.3 高效的社区支持
学习、开发难免遇到问题,官方技术支持和社区活跃度很重要。
本次评测 demo 开发期间,我们的同学(同时掌握 vue 和 react),在学习研究各个多端框架时,切实感受到由于语法、学习资料、社区的差异带来的学习门槛,吐出了很多槽。
2.4 活跃的开发迭代
开发者必须关心一个问题:该项目是否有人长期维护?
这个问题可以通过 github commits 频次、产品更新日志(changelog)、百度搜索指数等指标来衡量和对比。
github commits 频次
我们采集 2019 年 4 月份(时间为 4.1 ~ 4.30),每个项目在 github 上的 master 分支有 commit 的天数,结果如下:
Tips:
wepy的 master 分支无 commit,最新的 2.0.x 分支在 4 月份也仅 1 天有 commit 记录。
从 commit 的记录来看,taro、uni-app处于更新比较活跃的状态,wepy、mpvue则相对疲软,呈现无人维护之态。
产品更新日志
通过浏览产品更新日志,可确认产品是否在积极迭代、增加新功能、修复用户 bug。
wepy 官网 CHAGELOG:https://tencent.github.io/wepy/document.html#/changelog
mpvue 官网 Chang log:http://mpvue.com/change-log/
taro github 更新日志:https://github.com/NervJS/taro/blob/master/CHANGELOG.md
uni-app 官网更新日志:http://update.dcloud.net.cn/hbuilderx/changelog/1.9.9.20190522.html
2.5 多端复用
我们用事实说话,依然使用上述仿微博 App:https://github.com/dcloudio/test-framework依次发布到各平台,验证每个框架在各端的兼容性,结果如下:
测试结果说明:
?? 表示支持且功能正常,?? 表示不支持,其它则表示支持但存在部分 bug 或兼容问题
跨端框架,一方面要考虑框架提供的通用 api 跨端支持,同时还要考虑不同端的特色差异如何兼容。毕竟每个端都会有自己的特色,不可能完全一致。
taro:提供了 js 环境变量判断和统一接口的多端文件,可以在组件、js、文件方面扩展多端,不支持其他环节的分平台处理。
uni-app:提供了条件编译模型,所有代码包括组件、js、css、配置 json、文件、目录,均支持条件编译,可不受限的编写各端差异代码。
跨端框架,还涉及一个 ui 框架的跨端问题,评测结果如下:
uni-app:官方提供了uni ui,可全端运行;uni-app 还有一个插件市场,里面有很多三方 ui 组件,详见:https://ext.dcloud.net.cn/
最后补充跨端案例:
uni-app:多端案例丰富,官方示例已发布到 7 端 (包括 App 端)
结 语
真实客观的永远是实验和数据,而不是结论。不同需求的开发者,可以根据上述实验数据,自行得出自己的选型结论。
但作为一篇完整的评测,我们也必须提供一份总结,虽然它可能加入了我们的主观感受:
如果你是react系,那就用taro。
如果是vue系,那就用uni-app,uni-app在性能、周边生态和开发效率上更有优势。
如果你开发多端,uni-app和taro都可以,可根据自己熟悉的技术栈选择,相对而言uni-app的多端成熟度更高一些。
如有读者认为本文中任何评测失真,欢迎在这里报 issuse:
https://github.com/dcloudio/test-framework