自 2017-1-9
微信小程序诞生以来,历经2年多的迭代升级,已有数百万小程序上线,成为继Web、iOS、Android以后,第四大主流开发技术。javascript
与之相随,小程序的开发生态也在蓬勃发展,从最初的微信原生开发,到wepy
、mpvue
、taro
、uni-app
等框架依次出现,从刀耕火种演进为现代化开发,生态愈来愈丰富。css
选择多了,问题也就来了,开发小程序,该用原生仍是选择三方框架?html
首先,微信原生开发的槽点大多集中以下:前端
同时,开发者对三方框架,又老是有各类顾虑:vue
面对如此纠结的场景,很多热心开发者发布评测文章分享经验,但感受众说纷纭,过时信息太多。缺乏一份很是专业的、深度的,或者按现在流行的话来说,“硬核的”评测报告。java
作评测报告这件事,不一样于泛泛经验分享,其实很是花费时间。它须要:react
换言之:评测要想真,功夫得作深!webpack
uni-app
团队花费2个周时间完成本报告,并坚持每一个季度更新一次本评测报告。目前更新时间为2019年5月。git
本文从面向用户、面向开发者
两大维度七大细项,对微信原生及主流的wepy
、mpvue
、taro
、uni-app
开发框架进行横向对比,但愿给开发者在小程序框架选型时提供一种参考思路。本文基于各框架官网可采集到的公开数据及真实测试数据,但愿客观公正地评价各个框架的现状和优劣。但宥于利益相关,本文的观点极可能是带有偏向性的,你们能够带着批判的眼光来看待,如发现本文中有任何评测失真,欢迎在这里报 issuse。程序员
面向用户、面向开发者
维度,具体包括:
软件开发,首要目标是向用户提供完整、闭环的业务功能。
在web开发中,若是vue、react等框架的使用,形成开发者没法操做浏览器提供的全部api,那这样的框架确定是不成熟的。小程序开发也同样,任何开发框架,都不能限制底层的api调用。
而各类业务功能底层依赖微信暴漏的组件和接口(微信官网介绍的组件和 API 规范,也即微信原生API),三方框架是基于微信原生进行的二次封装,开发者此时常会有个疑问:小程序在不断的迭代升级,若是某项业务依赖于最新的小程序API,但三方框架还没有封装,该怎么办?
实际上就像web开发的vue、react同样,浏览器出了一个新API,并不会涉及vue、react的升级。本评测里的全部框架,都不会限制开发者调用底层能力。这里详细解释下缘由:
mpvue.request()
Taro.request()
,支持Taro 代码与小程序代码混写,可经过混写的方式调用框架还没有封装的小程序新增APIuni.request()
。同时支持条件编译,可在条件编译代码块中,随意调用各个平台新增的API及组件注:以上顺序,按各个框架的诞生顺序排序,下同。
故,三方框架都可调用全部小程序API,完成用户的业务需求,这个维度各框架是无差异的。
然而有差异的,是性能体验。
三方框架,内部大多作了层层封装,这些封装是否会增长运行负载,致使性能降低?尤为是与原生微信小程序开发相比性能怎么样,这是你们广泛关心的问题。
为客观的进行对比,咱们特地搭建了一个测试模型,详细以下:
开发内容:开发一个仿微博小程序首页的复杂长列表,支持下拉刷新、上拉翻页、点赞。
界面以下:
开发版本:一共开发了5个版本,包括微信原生版、wepy版、mpvue版、taro版、uni-app版,按照官网指引经过cli
方式默认安装。
测试代码开源(Github仓库地址:https://github.com/dcloudio/test-framework), Tips:如有同窗以为测试代码写法欠妥,欢迎提交 PR 或 Issus
测试机型:红米 Redmi 6 Pro、MIUI 10.2.2.0 稳定版(最新版)、微信版本 7.0.3(最新版)
测试环境:每一个框架开始测试前,杀掉各App进程、清空内存,保证测试机环境基本一致;每次从本地读取静态数据,屏蔽网络差别。
咱们以上述仿微博小程序为例,测试2个容易出性能问题的点:长列表加载、大量点赞组件的响应。
仿微博的列表是一个包含不少组件的列表,这种复杂列表对性能的压力更大,很适合作性能测试。
从触发上拉加载到数据更新、页面渲染完成,须要准确计时。人眼视觉计时确定不行,咱们采用程序埋点的方式,制定了以下计时时机:
Tips:setData
回调函数开头可认为是页面渲染完成的时间,是由于微信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
Tips1:wepy
官网的CHANGELOG,提到 v1.7.2 测试版本添加了对小程序原生组件的支持,实测坑不少,由于是测试版,官方在 issue 中也表示不推荐使用;按照官网文档,默认安装的 v1.7.3 正式版本并不支持原生组件
Tips2: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
> wepy
> mpvue
Tips:有人觉得uni-app和mpvue是同样的,早期uni-app确实使用过mpvue,但后来由于性能和vue语法支持度问题已经从新开发了。
长列表中的某个组件,好比点赞组件,点击时是否能及时的修改未赞和已赞状态?是这项测试的评测点。
测试方式:
onclick
函数开头开始计时,setData
回调函数开头结束计时;在红米手机(Redmi 6 Pro)上进行屡次测试,求其平均值,结果以下:
说明:也就是在列表数量为400时,微信原生开发的应用,点赞按钮从点击到状态变化须要111毫秒。
测试结果数听说明:
template
实现组件开发的框架(wepy/mpvue)性能组件数据更新性能测评:微信原生开发
,uni-app
,taro
> wepy
> mpvue
综上,本性能测试作了2个测试,长列表加载和组件状态更新,综合2个实验,结论以下:
微信原生开发手工优化
,uni-app
>微信原生开发未手工优化
,taro
> wepy
> mpvue
在知足用户业务需求的前提下,咱们谈谈开发者的需求,从以下几个维度比较:
选择开发团队熟悉的、能快速上手的DSL,是团队框架选型的基本点。
首先微信原生的开发语法,既像React
,又像Vue
,有点不三不四,对于开发者来讲,等于又要学习一套新的语法,大幅提高了学习成本,这一直被你们所诟病。
其它开发框架基本都遵循React、Vue(类Vue)语法,其主要目的:复用工程师的现有技术栈,下降学习成本。此时,框架对于原框架(React/Vue)语法的支持度就是一个重要的衡量标准,若是支持度较低、和原框架语法差别较大,则开发者无异于要学习一门新的框架,成本过高。
实际开发中发现,各个开发框架,都没有彻底实现Vue
、React
在web上的全部语法:
wepy
开发风格接近于 Vue.js
,属于类Vue
实现,相对微信原生开发算前进了一大步,但相比完整Vue
语法还有较大差距,开发时须要单独学习它的规则;
mpvue
、uni-app
框架基于 Vue.js
核心,经过修改 Vue.js
的 runtime
和 compiler
,实现了在小程序端的运行。mpvue
支持的Vue语法略少,uni-app
则基本支持绝大多数vue语法,如filter
、复杂 JavaScript
表达式等;
taro
对于 JSX
的语法支持度,也达到了绝大多数都支持的完善程度。
DSL语法支持评测:taro
,uni-app
> mpvue
> wepy
> 微信原生
官方文档、问题搜索、示例demo的完备度方面:
教学课程方面:
学习资料完善度评测:微信原生 > uni-app
> mpvue
, taro
> wepy
开发体验层面,处于明显劣势的是微信原生开发,主要差距在于:
其它小程序开发框架均支持cli
模式,能够在主流前端工具中开发,且基本都带有d.ts的语法提示库。
因为mpvue
、uni-app
、taro
直接支持vue
、react
语法,配套的ide工具链较丰富,着色、校验、格式化完善;wepy
要弱一些,有部分三方维护的vscode插件。
好的开发工具,绝对能够大幅提高开发体验,这个维度上,明显高出一截的框架是uni-app
,其出品公司同时也是HBuilder的出品公司,DCloud.io。HBuilder是四大主流前端开发工具(可对比百度指数),其为uni-app
作了不少优化,故uni-app
的开发效率、易用性非其余框架可及。
开发体验维度,对比结果:uni-app
> taro
,mpvue
> wepy
> 微信原生
这里能够输出一个结论:若是你须要工程化能力,那就直接忘了微信原生开发吧。
学习、开发不免遇到问题,官方技术支持和社区活跃度很重要。
本次评测demo开发期间,咱们的同窗(同时掌握vue和react),在学习研究各个多端框架时,切实感觉到因为语法、学习资料、社区的差别带来的学习门槛,吐出了不少槽。
综合评估,本项评测结论:微信原生
, uni-app
> taro
> mpvue
> wepy
开发者必须关心一个问题:该项目是否有人长期维护?
这个问题能够经过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。
咱们分别查看各框架官方连接的更新日志(CHANGELOG),下方是连接地址:
经过产品更新日志对比,微信原生、taro
、uni-app
三者更新频繁,bug修复、新功能补充都处于比较紧凑的状态;而mpvue
、wepy
则已有长时间没有版本发布,wepy
甚至有将近1年时间未发布正式版本,开发者选型需谨慎。
随着微信小程序的火爆,支付宝、百度、字节跳动等公司也前后进入小程序领域,这些公司个个日活过亿,坐拥海量用户,企业主但愿将本身的业务触达每一个用户,无论这个用户在哪一个小程序中。
需求转接到程序员这里,程序员怎么办?难道真的每一个平台处处搬砖吗?此时,一套代码、多端发布就成为不少程序员的梦想,小程序跨端框架应运而生。
现实真能如此理想吗?每一个跨端框架可否真的像官网宣传的那样,实现开发一次,发布到全部小程序平台?甚至和H5平台复用代码?
咱们用事实说话,依然使用上述仿微博App,依次发布到各平台,验证每一个框架在各端的兼容性,结果以下:
测试结果说明:
经过这个简单的例子能够看出,跨端支持度测评结论: uni-app
,taro
> mpvue
> 原生微信小程序
、wepy
可是仅有上面的测试还不全面,实际业务要比这个测试例复杂不少。但咱们无法开发不少复杂业务作评测,因此还须要再对照各家文档补充一些信息。 因为每一个框架的文档中都描述了各类组件和API的跨端支持程度。咱们过了几家的文档,发现各家基本是以微信小程序为基线,而后把各类组件和API在其余端实现了一遍:
taro
:H5端实现了大部分微信的APIuni-app
:组件、API、配置,大部分在各个端均已实现,个别API有说明在某些端不支持。能够看出uni-app是完整在H5端实现了一套微信模拟器跨端框架,一方面要考虑框架提供的通用api跨端支持,同时还要考虑不一样端的特点差别如何兼容。毕竟每一个端都会有本身的特点,不可能彻底一致。
taro
:提供了js环境变量判断和统一接口的多端文件,能够在组件、js、文件方面扩展多端,不支持其余环节的分平台处理。uni-app
:提供了条件编译模型,全部代码包括组件、js、css、配置json、文件、目录,均支持条件编译,可不受限的编写各端差别代码。跨端框架,还涉及一个ui框架的跨端问题,评测结果以下:
最后补充跨端案例:
综合以上信息,本项的最终评测结论:uni-app
> taro
> mpvue
> 原生微信小程序
、wepy
这里能够输出一个结论,若是有多端发布需求,微信原生开发、wepy
这两种方式能够直接排除了。
真实客观的永远是实验和数据,而不是结论。不一样需求的开发者,能够根据上述实验数据,自行得出本身的选型结论。
但做为一篇完整的评测,咱们也必须提供一份总结,虽然它可能加入了咱们的主观感觉:
若是你只开发微信小程序,不作多端,那么使用uni-app
、taro
是更优的选择,他们至关于web世界的vue和react,有了这些工具,再也不须要使用原生wxml开发。
setdata
,而且注意其工程化能力很是弱react
系,那就用taro
vue
系,那就用uni-app
,uni-app
在性能、周边生态和开发效率上更有优点若是你开发多端,uni-app
和taro
均可以,可根据本身熟悉的技术栈选择,相对而言uni-app
的多端成熟度更高一些。
若有读者认为本文中任何评测失真,欢迎在这里报 issuse。