跨端开发框架深度横评

我是创始人李岩:很抱歉!给自己产品做个广告,点击进来看看。  

上周,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. 跨端支持度如何?
    2. 性能如何?
    3. 学习门槛
    4. 工具与周边生态

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  >  chameleonmpvue  > 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 测试数据不完整?

mpvuewepy  诞生之初,微信小程序尚不支持 自定义组件 ,无法进行组件化开发; mpvuewepy  为解决这个问题,将用户编写的 Vue 组件,编译为 WXML 中的 模板(template) ,变相实现了组件化开发能力,提高代码复用性,这在当时的技术条件下是很棒的技术方案。

但如此方案,在复杂组件较多的页面,会大量增加 dom 节点,甚至超出微信的 dom 节点数限制。我们在 红米手机(Redmi 6 Pro)上实测,页面组件超过500个时, mpvuewepy  实现的仿微博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-apptaro  都在调用 setData 之前自动做 diff 计算,每次仅传递有变化的数据。

例如当前页面有20条数据,触发上拉加载时,会新加载20条数据,此时原生框架通过如下代码测试时, setData 会传输40条数据

  1. data : {
  2. listData : []
  3. },
  4. onReachBottom () { //上拉加载
  5. let listData = this . data . listData ;
  6. listData . push (... Api . getNews ()); //新增数据
  7. this . setData ({
  8. listData
  9. }) //全量数据,发送数据到视图层
  10. }

开发者使用微信原生框架,完全可以自己优化,精简传递数据,比如修改如下:

  1. data : {
  2. listData : []
  3. },
  4. onReachBottom () { //上拉加载
  5. // 通过长度获取下一次渲染的索引
  6. let index = this . data . listData . length ;
  7. let newData = {}; //新变更数据
  8. Api . getNews (). forEach (( item ) => {
  9. newData [ 'listData[' + ( index ++) + ']' ] = item //赋值,索引递增
  10. })
  11. this . setData ( newData ) //增量数据,发送数据到视图层
  12. }

经过如上优化修改后,再次测试,微信原生框架性能数据如下:

组件数量 微信原生框架(优化前) 微信原生框架(优化后) 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-apptaro  相比微信原生,性能差距并不大。

这个结果,和web开发类似,web开发也有原生js开发、vue、react框架等情况。如果不做特殊优化,原生js写的网页,性能经常还不如vue、react框架的性能。

也恰恰是因为 Vuereact 框架的优秀,性能好,开发体验好,所以原生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 创造循环组件一条

mpvueuni-app  框架基于  Vue.js  核心,通过修改  Vue.js  的  runtime  和  compiler ,实现了在小程序端的运行,支持绝大部分的Vue语法; uni-app  编译到微信端曾经使用过 mpvue ,但后来重写框架,支持了更多vue语法如 filter 、复杂  JavaScript  表达式等;

wepychameleon  都是  类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 没有视频教程,但官方发布了掘金小册; wepychameleon 还没有专业教程。

学习资料完善度评测: uni-app  >  mpvue  ,  taro  >  chameleon  >  wepy

技术支持和社区活跃度

开发难免遇到问题,官方技术支持和社区活跃度很重要。

目前看, uni-apptarochameleon 都有专职人员做技术支持, 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的语法提示库。
由于 mpvueuni-apptaro 直接支持 vuereact 语法,配套的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-appmpvue 的插件生态是互通的,都是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 未被百度指数收录,说明其搜索量和包含该关键字的网页数量都不够多。
  • tarochameleon  的名称取自于已存在的名称,实际指代开发框架的指数应该更低。

案例

仅看发布到微信小程序的案例,数量和质量综合对比,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 ,都只是渲染器,能力部分还需要开发者写原生代码,这就无法跨端了。 exporeact native 强的是多封装了一些能力,但也带来新的限制。

uni-app 的App端,是一个真的小程序引擎,又补充了可选的weex引擎。这也是 uni-app 在App端能够提供比其他跨端框架更好兼容性的原因。

而这个引擎,是另一个开源项目,叫 h5p ,这个引擎是部分开源状态。

整个业内目前还不存在一个完全开源的小程序引擎。

不过 uni-app 的App端使用许可是完全免费,可以放心使用。

其实也不用好奇为什么DCloud会有小程序引擎,因为业内第一个做小程序的并不是微信,而是DCloud。

关于App端,其实可以再写出一篇很长的专业评测。后续 uni-app 团队会再做一篇App端与 react nativeweexcordovaflutter 等框架的对比。

2. 转换和混写

taro 提供了原生小程序转换为 taro 工程的转换器,也支持在原生小程序里部分页面嵌入 taro 编写的页面,这是 taro 的特色,其他跨端框架没有提供。这对于降低入门门槛有不少帮助。

结语

真实客观的永远是实验和数据,而不是结论。不同需求的开发者,可以根据上述实验数据,自行得出自己的选型结论。

但作为一篇完整的评测,我们也必须提供一份总结,虽然它可能加入了我们的主观感受:

如果你想多端开发,提升效率,不想踩太多坑, uni-app 相对更完善。

如果你只开发微信小程序,不做多端,那么使用 uni-app 、微信原生开发、 taro 是更优的选择。

  • 如果使用微信原生开发,需要注意手动写优化代码来控制 setdata
  • 如果你是 react 系,那就用 taro
  • 如果是 vue 系,那就用 uni-appuni-app 在性能、周边生态和开发效率上更有优势

如果你主要为了微信端和H5端,那么 uni-apptaro 都可以。可以根据自己熟悉的技术栈选择。

如果你主要需要跨App端, uni-app 兼容性更好,其他框架的App端差异过大。如果你只关心App,不关心小程序和H5,那欢迎关注我们后续的评测: uni-appcordovareact nativeflutter 的深度比较。

如果你主要为了各家小程序,且不用复杂组件,那除了 uni-apptarompvue 也是不错的选择。 mpvue 发布2.0版本后,搜索指数明显爬升,希望能持续更新,迎来二次繁荣。

chameleon 发布不久,提供的组件和API还很少,但其未来的规划比较令人期待,值得关注。

这篇评测写完后,小编有点惴惴不安。

一方面本评测不太温和,容易得罪人。但我们相信,这样的评测,会激起所有跨端框架从业者的斗志,让大家投入更多去完善产品,这对整个产业、对前端开发者,是大好事。

另一方面,读者可能会以为现阶段的 uni-app 很完美,其实我们深知 uni-app 还有很多需要完善的地方。 uni-app 团队也将持续投入心血,为中国的前端开发者造福!

如有读者认为本文中任何评测失真,欢迎在这里报 issues 。

随意打赏

百度深度学习框架深度学习框架开源中国设计模式深度框架
提交建议
微信扫一扫,分享给好友吧。