微信小程序如火如荼,各家小程序快速跟进,继App、H5以后,小程序平台已跃升为第三大流量平台,那现阶段快速开发小程序的更优方案是什么?选择原生开发,仍是借助跨端框架?每一个框架又有何差别?javascript
本文经受权转载,以下为原文,enjoy!css
以前 Taro 团队发布了一篇《小程序多端框架全面测评》,让开发者对业界主流的跨端框架,有了初步认识。感谢 Taro 团队的付出。html
不过横评这件事,要想获得更精确的结论,其实很是花费时间。它须要:前端
咱们 uni-app
团队投入两周完成了这个深度评测,下面咱们就分享下,实际开发不一样框架的测试例时遇到的问题,以及在各端的兼容测试结果。在本文里,咱们团队基于真实测试数据及各框架官网可采集到的公开数据,但愿客观公正地评价各个框架的选型和优劣。但宥于利益相关,本文的观点极可能是带有偏向性的,你们能够带着批判的眼光去看待。vue
开发内容:开发一个仿微博小程序首页的复杂长列表,支持下拉刷新、上拉翻页、点赞。java
界面以下:
react
开发版本:一共开发了6个版本,包括微信原生版、wepy版、mpvue版、taro版、uni-app版、chameleon版(以这些产品发布时间排序,下同),按照官网指引经过cli
方式默认安装。git
测试代码开源(Github仓库地址:https://github.com/dcloudio/test-framework),
Tips:如有同窗以为测试代码写法欠妥,欢迎提交 PR 或 Issus程序员
测试机型:红米 Redmi 6 Pro、MIUI 10.2.2.0 稳定版(最新版)、微信版本 7.0.3(最新版)github
测试环境:每一个框架开始测试前,杀掉各App进程、清空内存,保证测试机环境基本一致;每次从本地读取静态数据,屏蔽网络差别。
开发一次,处处运行,是每一个程序员的梦想。但现实每每变成开发一次,处处调错。
各个待评测框架,是否真得如宣传的那样,一次开发、多端发布?
咱们将上述仿微博App依次发布到各平台,验证每一个框架在各端的兼容性,结果以下:
测试结果说明:
wepy
2.0 宣称版已支持其余家小程序,本测试基于wepy
官网指引安装的wepy-cli
版本为1.7.3,尚不支持多端chameleon
官网未找到stopPullDownRefresh
定义,中止页面下拉刷新需分平台编写经过这个简单的例子能够看出,跨端支持度测评结论: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
扩展组件库,可全端运行,但组件数量略少,详见最后补充跨端案例:
综合以上信息,本项的最终评测结论:uni-app
> taro
> chameleon
> mpvue
> wepy
、原生微信小程序
跨端框架基本都是compiler
+ runtime
模式,引入的runtime
是否会下降运行性能?
尤为是与原生微信小程序开发相比性能怎么样,这是你们广泛关心的问题。
咱们依然以上述仿微博小程序为例,测试2个容易出性能问题的点:长列表加载、大量点赞组件的响应。
仿微博的列表是一个包含不少组件的列表,这种复杂列表对性能的压力更大,很适合作性能测试。
从触发上拉加载到数据更新、页面渲染完成,须要准确计时。人眼视觉计时确定不行,咱们采用程序埋点的方式,制定了以下计时时机:
Tips:setData
回调函数开头可认为是页面渲染完成的时间,是由于微信setData
定义以下(微信规范):
字段 | 类型 | 必填 | 描述 |
---|---|---|---|
data | Object | 是 | 此次要改变的数据 |
callback | Function | 否 | setData引发的界面更新渲染完毕后的回调函数 |
测试方式:从页面空列表开始,经过程序自动触发上拉加载,每次新增20条列表,记录单次耗时;固定间隔连续触发 N 次上拉加载,使得页面达到 20*N 条列表,计算这 N 次触发上拉到渲染完成的平均耗时。
测试结果以下:
说明:以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
相比微信原生,性能差距并不大。
这个结果,和web开发相似,web开发也有原生js开发、vue、react框架等状况。若是不作特殊优化,原生js写的网页,性能常常还不如vue、react框架的性能。
也偏偏是由于Vue
、react
框架的优秀,性能好,开发体验好,因此原生js开发已经逐渐减小使用了。
复杂长列表加载下一页评测结论:微信原生开发手工优化
,uni-app
>微信原生开发未手工优化
,taro
> chameleon
> wepy
> mpvue
注:有人觉得uni-app和mpvue是同样的,早期uni-app确实使用过mpvue,但后来由于性能和vue语法支持度问题已经从新开发了。
长列表中的某个组件,好比点赞组件,点击时是否能及时的修改未赞和已赞状态?是这项测试的评测点。
测试方式:
onclick
函数开头开始计时,setData
回调函数开头结束计时;在红米手机(Redmi 6 Pro)上进行屡次测试,求其平均值,结果以下:
说明:也就是在列表数量为400时,微信原生开发的应用,点赞按钮从点击到状态变化须要111毫秒。
测试结果数听说明:
template
实现组件开发的框架(wepy/mpvue)性能组件数据更新性能测评:微信原生开发
,uni-app
,taro
> chameleon
> wepy
> mpvue
综上,本性能测试作了2个测试,长列表加载和组件状态更新,综合2个实验,结论以下:
微信原生开发手工优化
,uni-app
>微信原生开发未手工优化
,taro
> chameleon
>> wepy
> mpvue
主流跨端框架基本都遵循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
chameleon:基础API文档完整,具体使用问题资源较少,问题搜索效果通常,示例demo只包含基础功能,仅发布了微信一端。详见
教学课程方面:
学习资料完善度评测:uni-app > mpvue , taro > chameleon > wepy
开发不免遇到问题,官方技术支持和社区活跃度很重要。
本次评测demo开发期间,咱们的同窗(同时掌握vue和react),在学习研究各个多端框架时,切实感觉到因为语法、学习资料、社区的差别带来的学习门槛,吐出了不少槽。
综合评估,本项评测结论:uni-app
> taro
> mpvue
> wepy
> chameleon
Tips:本测评忽略React、Vue两框架自身的学习门槛
全部多端框架均支持cli
模式,能够在主流前端工具中开发。
各框架基本都带有d.ts的语法提示库。
因为mpvue
、uni-app
、taro
直接支持vue
、react
语法,配套的ide工具链较丰富,着色、校验、格式化完善,chameleon
针对部分编辑器推荐了插件,wepy
的有一些三方维护的vscode插件。
工具属性维度,明显高出一截的框架是uni-app
,其出品公司同时也是HBuilder的出品公司,DCloud.io。
HBuilder/HBuilderX系列是四大主流前端开发工具(可对比百度指数),其为uni-app
作了不少优化,故uni-app
的开发效率、易用性非其余框架可及。
固然对于不习惯HBuilderX的开发者而言,uni-app
的这个优点没法体现。
一个底层框架,其周边配套很是重要,好比ui库、js库、项目模板。
值得注意的是,uni-app
和mpvue
的插件生态是互通的,都是vue插件。因此双方还联合举办了插件大赛。这个联合生态的周边丰富度,是目前各个框架中最丰富的。
综上比较,工具和周边生态评测结论:uni-app
,mpvue
> wepy
> taro
> chameleon
github star:
github star 数对比: taro
> wepy
>mpvue
> uni-app
> chameleon
Tips:
百度指数
百度指数表明了开发者的搜索量和包含关键字的网页数量。以下是各跨端框架近7天(2019-03-24 ~ 2019-03-30)的百度指数:
Tips:
wepy
未被百度指数收录,说明其搜索量和包含该关键字的网页数量都不够多。能够看出一个较大的冲突就是uni-app的star数量较少,而百度指数较高。
根据咱们分析,star数量和产品发布时间有关,也和用户使用习惯有关。大多框架的交流互动主要是github的issus,而uni-app
的开发者在其问答社区交流,github页面访问量较低。另外咱们观察了一周的star的增速,每周star新增量,uni-app是最多的。
案例
咱们对比了每一个框架公布的案例,以下的框架名称的超连接已指向其案例页面,能够直接访问。
仅看发布到微信小程序的案例,数量和质量综合对比,wepy > mpvue > taro , uni-app > chameleon
若是看多端案例,综合对比,uni-app > taro > mpvue > wepy > chameleon
wepy
:的知名案例较多,包括不少一线互联网公司。mpvue
、taro
:跨端框架的出品方自己为一线互联网公司,其内部项目会使用这些框架,经受过实战考验。除内部项目外,暂无其余一线互联网公司使用。uni-app
:案例不少,官方数据已经超过10w+。但以创业者和政企单位为主,暂无一线开发者使用。chameleon
:未找到案例,没法参与本评测。1. App侧的补充说明
目前有taro
、uni-app
、chameleon
三家框架支持App端。但在App端大可能是三方产品,好比taro
使用expo
(一个基于react native
的封装库),chameleon
使用weex
。
无论react native
仍是weex
,其架构与小程序架构彻底不一样,从排版到API能力都差异很大,因此这类产品跨App端时兼容性较差。
uni-app
的App端,内置一个完整小程序引擎,并补充了可选的weex
引擎给对性能要求更高的开发者。这也是uni-app
在App端可以正常运行微信小程序代码的缘由。
整个业内目前还不存在一个彻底开源的小程序引擎(微信、百度、支付宝、头条的小程序引擎源码均未开源)。uni-app
的小程序引擎不是全开源,而是能力层开源,中控未开源。
因此可能各家的多端框架,在App端都有不完美的地方,须要开发者使用时注意。
其实App引擎并不是前端领域,是原生领域的另外一个竞技场。后续uni-app
会再出一个与cordova
、react native
、weex
、flutter
的横评。
2. 转换和混写
taro
提供了原生小程序转换为taro
工程的转换器,也支持在原生小程序里部分页面嵌入taro
编写的页面。uni-app
和chameleon
提供了转换的文档,没有转换工具。
真实客观的永远是实验和数据,而不是结论。不一样需求的开发者,能够根据上述实验数据,自行得出本身的选型结论。
但做为一篇完整的评测,咱们也必须提供一份总结,虽然它可能加入了咱们的主观感觉:
若是你只开发微信小程序,不作多端,uni-app
仍然是最好的选择,除非你有兴趣手动优化原生小程序的代码,或者对react很是熟悉不肯意学习vue也可使用taro
。
若是你主要为了统一各家小程序,uni-app
仍然是最好的选择,taro
次之。
若是你还须要跨端到H5侧,那么uni-app
是最好的选择。
若是你还须要跨端到App侧,那么uni-app
是惟一可商用的选择。
固然,uni-app
也距离完美尚远,只是在参比框架中相对有优点。uni-app
团队也仍继续大力投入,持续填坑,帮助开发者提高投入产出、提高开发体验!
若有读者认为本文中任何评测失真,欢迎在这里报 issuse。