跨端开拓框架深度横评彩民之家高手论坛

2019-10-13 04:21 来源:未知

预加载webview

预加载webview,微信会预加载多一个wkwebview(ios平台)放后台,用户打开小程序时省去初始化wkwebview时间。

1 赞 收藏 评论

彩民之家高手论坛 1

小程序开发有哪些痛点?

  • 频繁调用 setData及 setData过程中页面跳闪
  • 组件化支持能力太弱
  • 不能使用 less、scss 等预编译器
  • request 并发次数限制
  • 开发内容:开发一个仿微博小程序首页的复杂长列表,支持下拉刷新、上拉翻页、点赞。

  • 界面如下:

    彩民之家高手论坛 2image

  • 开发版本:一共开发了6个版本,包括微信原生版、wepy版、mpvue版、taro版、uni-app版、chameleon版(以这些产品发布时间排序,下同),按照官网指引通过cli方式默认安装。

  • 测试代码开源(Github仓库地址: PR 或 Issus*

  • 测试机型:红米 Redmi 6 Pro、MIUI 10.2.2.0 稳定版、微信版本 7.0.3

  • 测试环境:每个框架开始测试前,杀掉各App进程、清空内存,保证测试机环境基本一致;每次从本地读取静态数据,屏蔽网络差异。

  • 测试维度:

    1. 跨端支持度如何?
    2. 性能如何?
    3. 学习门槛
    4. 工具与周边生态

我看小程序

我想从技术的角度来谈谈我对微信小程序的理解,我觉得小程序本身是一个非常优秀的Hybrid App的技术方案。有很多值得学的地方,可以应用到我们Hybrid App的技术方案设计中来。了解和学习小程序技术原理也能更好的优化我们的代码。

状态管理

  • wepy 可引用Redux和Mbox,目前wepy的脚手架内已经集成了redux,选择需要即可;
  • mpVue使用vuex;
  • taro使用Redux;

如何选择适合自己的项目

  • 如果只需要做一个微信小程序则根据自己的擅长框架选择mpvue或taro
  • 如果是当前老项目想像向程序迁移同时老项目又是使用vue开发,建议使用mpvue或wepy
  • 如果是老项目使用react开发且需要部分迁移小程序,建议使用taro
  • 如果是新项目且新项目需要同时支持微信小程序和支付宝小程序, 建议使用原生开发,因为目前框架的转译支付宝小程序支持并不是很好,且出了问题不好定位修改, 但如果是小demo不涉及太多逻辑的项目都可以使用框架作为尝鲜; 但如果是涉及太多交互逻辑的则不建议使用框架转译,由于支付宝小程序在视图层基本与小程序一致所以建议手动更改替换部分方法和全局替换一些属性或文件名,如wxml替换为axml这种, 手动转换时间比大概是四比一; 当然如果人手足够一端开发一个是最好的......

时刻前端新鲜技术推送,定期前端精品文章分享,欢迎关注公众号前端小苑

DSL语法支持度

主流跨端框架基本都遵循React、Vue语法,其主要目的:复用工程师的现有技术栈,降低学习成本。此时,跨端框架对于原框架(React/Vue)语法的支持度就是一个重要的衡量标准,如果支持度较低、和原框架语法差异较大,则开发者无异于要学习一门新的框架,成本太高。

实际开发中发现,各个多端框架,都没有完全实现vue、react在web上的所有语法:taro 对于 JSX 的语法支持是相对完善的,其文档中描述未来版本计划,

更多的 JSX 语法支持,1.3 之后限制生产力的语法只有只能用 map 创造循环组件一条

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

wepychameleon 都是 类Vue 的实现,仅支持 Vue 的部分语法,开发时需要单独学习它们的规则;

DSL语法支持评测:taro,uni-app > mpvue > wepy,chameleon

Taro

Taro是由京东团队开源的一套遵循 React 语法规范的多端开发解决方案。本身我对React和Taro都不是很了解,就不多解释了。具体可以看开发团队的博客和代码了解更多细节多端统一开发框架 – Taro
彩民之家高手论坛 3

事件处理

mpvue目前全支持小程序的事件处理器,引入了 Vue.js 的虚拟 DOM ,在前文模版中绑定的事件会被挂在到 vnode 上,同时 compiler 在 wxml 上绑定了小程序的事件,并做了相应的映射,所以在真实点击的时候通过 runtime 中 handleProxy 事件类型分发到 vnode 的事件上,同 Vue 在 WEB 的机制一样,可以做到无损支持。同时还顺便支持了自定义事件和 $emit 机制。

事件映射表,左侧为 WEB 事件,右侧为 小程序 对应事件

彩民之家高手论坛 4

踩坑注意:

  • 列表中没有的原生事件也可以使用例如 bindregionchange 事件直接在 dom 上将bind改为@ @regionchange,同时这个事件也非常特殊,它的 event type 有 begin 和 end 两个,导致我们无法在handleProxy 中区分到底是什么事件,所以你在监听此类事件的时候同时监听事件名和事件类型既 <map @regionchange="functionName" @end="functionName" @begin="functionName">
  • 小程序能力所致,bind 和 catch 事件同时绑定时候,只会触发 bind ,catch 不会被触发,要避免踩坑
  • 事件修饰符 .stop 的使用会阻止冒泡,但是同时绑定了一个非冒泡事件,会导致该元素上的 catchEventName 失效! .prevent 可以直接干掉,因为小程序里没有什么默认事件,比如submit并不会跳转页面 .capture 支持 1.0.9 .self 没有可以判断的标识 .once也不能做,因为小程序没有 removeEventListener, 虽然可以直接在 handleProxy 中处理,但非常的不优雅,违背了原意,暂不考虑
  • 其他 键值修饰符 等在小程序中压根没键盘,所以......

wepy事件绑定区别于vue,根据原生小程序事件提供了语法优化

彩民之家高手论坛 5

Taro 元素的事件处理和 DOM 元素的很相似。但是有一点语法上的不同:

Taro 事件绑定属性的命名采用驼峰式写法,而不是小写。 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串 (DOM 元素的写法)。

例如,传统的微信****小程序模板:

彩民之家高手论坛 6

Taro 中稍稍有点不同:

彩民之家高手论坛 7

在 Taro 中另一个不同是你不能使用 catchEvent 的方式阻止事件冒泡。你必须明确的使用 stopPropagation。例如,阻止事件冒泡你可以这样写:

彩民之家高手论坛 8

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次后停止(页面达到400条微博),计算这20次的平均耗时,结果微信原生在这20次 触发上拉 -> 渲染完成 的平均耗时为876毫秒,最快的uni-app是741毫秒,最慢的mpvue是4493毫秒

大家初看这个数据,可能比较疑惑,别急,下方有详细说明

说明1:为何 mpvue/wepy 测试数据不完整?

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

但如此方案,在复杂组件较多的页面,会大量增加 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条记录时,taro 性能数据也比微信原生框架更好。

微信原生框架耗时主要在setData调用上,开发者若不单独优化,则每次都会传递大量数据;而 uni-apptaro 都在调用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 => { newData['listData['      ']'] = item //赋值,索引递增 }) this.setData //增量数据,发送数据到视图层}

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

|组件数量 | 微信原生框架 |微信原生框架 |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

mpvue

由美团团队开发,mpvue和wepy一样也是在小程序上提供了类vue.js的开发体验。作为后来者,抢占了很多wepy的市场份额(ps:我们团队近期也在考虑从wepy迁移到mpvue)。这个框架的原理相比wepy要更加复杂一点,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,提供了更加接近于vue.js的开发体验。

彩民之家高手论坛 9

学习资料完善度

  • 官方文档、搜索系统的完备度方面:uni-app文档内容丰富,示例demo完备,taro次之,其他几个框架相对要弱一些。mpvue文档虽少,但其概念不复杂,也没有支持H5、App,组件、API文档都可直接看微信的文档,学习难度倒也很低。
  • 教程方面:uni-app官方有视频教程,不少三方专业培训机构也录制的uni-app教程,包括腾讯课堂自家NEXT学院也录制了uni-app培训视频课,公开售卖;mpvue在腾讯课堂也有三方视频教程售卖;taro没有视频教程,但官方发布了掘金小册;wepychameleon还没有专业教程。

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

多webview架构

多webview的页面架构,小程序每新开一个页面,都会用一个新的webview来渲染。为了防止webview对内存的消耗。小程序限制层级不能超过10层。

为什么使用第三方框架?

  • 只要熟悉vue或react即可快速上手,学习成本低
  • 一套代码可在多端编译运行(微信,支付宝,h5,RN) 支付宝小程序暂不完善
  • 组件化开发,完美解决组件隔离,组件嵌套,组件通信等问题
  • 支持使用第三方 npm 资源
  • 使小程序可支持 Promise,解决回调烦恼
  • 可使用 Generator Function / Class / Async Function 等特性,提升开发效率
  • 对小程序本身的优化,如生命周期的补充,性能的优化等等
  • 支持样式编译器: Scss/Less,模板编译器,代码编译器:Babel/Typescript。
  • mpvue:微信端案例丰富,未见其它端案例
  • taro:微信端案例丰富,百度、支付宝、H5端亦有少量案例
  • uni-app:微信、App、H5三端案例丰富,官方示例已发布到6端
  • chameleon:未看到任何端案例

那些年我们踩过的坑

  • css样式不能引用本地图片资源,只能引用线上资源(background-image),引用本地图片资源只能用<image>标签。
  • {{}}不能执行函数方法,{{}}只支持基本的简单运算和ES6拓展运算符。如价格格式化这种常用的处理,只能在js代码中处理好然后再模板中渲染。
JavaScript

this.setData({ price: this.formatPrice(this.data.price) })

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f634e5286f536526954-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e5286f536526954-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f634e5286f536526954-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f634e5286f536526954-1" class="crayon-line">
this.setData({
</div>
<div id="crayon-5b8f634e5286f536526954-2" class="crayon-line crayon-striped-line">
 price: this.formatPrice(this.data.price)
</div>
<div id="crayon-5b8f634e5286f536526954-3" class="crayon-line">
})
</div>
</div></td>
</tr>
</tbody>
</table>
  • 可以通过wxs模块解决{{}}中不能执行函数的问题。可以做到模拟vue.js中过滤器的功能。
JavaScript

&lt;!-- wxml模板 --&gt; &lt;wxs src="../../modules/formatPrice.wxs"
module="tools" /&gt;
&lt;view&gt;价格:{{tools.formatPrice(price)}}&lt;/view&gt; //
wxs模块 var formatPrice = function (price){ price = price &gt;&gt;
0; return Number(price / 100).toFixed(2); } module.exports = {
formatPrice }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e52877119487867-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f634e52877119487867-13">
13
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f634e52877119487867-1" class="crayon-line">
&lt;!-- wxml模板 --&gt;
</div>
<div id="crayon-5b8f634e52877119487867-2" class="crayon-line crayon-striped-line">
&lt;wxs src=&quot;../../modules/formatPrice.wxs&quot; module=&quot;tools&quot; /&gt;
</div>
<div id="crayon-5b8f634e52877119487867-3" class="crayon-line">
 
</div>
<div id="crayon-5b8f634e52877119487867-4" class="crayon-line crayon-striped-line">
&lt;view&gt;价格:{{tools.formatPrice(price)}}&lt;/view&gt;
</div>
<div id="crayon-5b8f634e52877119487867-5" class="crayon-line">
// wxs模块
</div>
<div id="crayon-5b8f634e52877119487867-6" class="crayon-line crayon-striped-line">
var formatPrice = function (price){
</div>
<div id="crayon-5b8f634e52877119487867-7" class="crayon-line">
    price = price &gt;&gt; 0;
</div>
<div id="crayon-5b8f634e52877119487867-8" class="crayon-line crayon-striped-line">
    return Number(price / 100).toFixed(2);
</div>
<div id="crayon-5b8f634e52877119487867-9" class="crayon-line">
}
</div>
<div id="crayon-5b8f634e52877119487867-10" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f634e52877119487867-11" class="crayon-line">
module.exports = {
</div>
<div id="crayon-5b8f634e52877119487867-12" class="crayon-line crayon-striped-line">
    formatPrice
</div>
<div id="crayon-5b8f634e52877119487867-13" class="crayon-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>
  • 小程序不支持分享链接到朋友圈,暂时的通用做法是生成保存有页面小程序码的图片到本地相册。又用户自行发朋友圈转发。前端可以利用canvas来实现,减轻服务端压力。但是会有图片锯齿不清晰的问题。建议预览图和保存到真机的图片采用不同的尺寸。保存在真机的图片按照750的宽度实现。相比于预览图要大一些,这样保存到手机的图片会清晰很多。
  • 小程序布局采用rpx单位,UI稿按照750的宽度出图。可直接使用UI稿的尺寸。但是在某些机型上1rpx会无法显示。可以用H5的方式实现1px效果。
  • iphoneX吸底按钮的适配,可以用媒体查询获取wx.getSystemInfo获取机型。参考
JavaScript

@media only screen and (device-width : 375px) and (device-height :
812px) and (-webkit-device-pixel-ratio : 3) { }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f634e5287c595320097-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e5287c595320097-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f634e5287c595320097-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f634e5287c595320097-4">
4
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f634e5287c595320097-1" class="crayon-line">
@media only screen 
</div>
<div id="crayon-5b8f634e5287c595320097-2" class="crayon-line crayon-striped-line">
    and (device-width : 375px) 
</div>
<div id="crayon-5b8f634e5287c595320097-3" class="crayon-line">
    and (device-height : 812px) 
</div>
<div id="crayon-5b8f634e5287c595320097-4" class="crayon-line crayon-striped-line">
    and (-webkit-device-pixel-ratio : 3) { }
</div>
</div></td>
</tr>
</tbody>
</table>
  • 页面A -> 页面B,页面B的操作触发了页面A的数据更新。返回更新页面A的数据,通常有两种方式来实现(我司采用了方案二):
    1. 在页面A监听onShow事件,在onShow事件触发时无脑更新页面数据。
    2. 通过EventBus来实现跨页面通信。
  • 复杂组件的开发,省市区三级联动选择器的开发,获取微信地址库的地址的编码和业务采用的省市区编码对不上。
  • 页面路径的层级,最大不能超过10层。
  • 小程序小程序分包加载,微信对小程序包的大小有如下限制。
  • 整个小程序所有分包大小不超过 8M
  • 单个分包/主包大小不能超过 2M

小程序框架对比:WePY / mpvue / Taro

在这里我通过对目前已开源的三种常用小程序框架做一个综合对比, 还有一个叫nanchi的基于react的小程序转译框架,由于没来的及研究暂不做比较。

腾讯团队开源的一款类vue语法规范的小程序框架,借鉴了Vue的语法风格和功能特性,支持了Vue的诸多特征,比如父子组件、组件之间的通信、computed计算属性、wathcer监听器、props传值、slot槽分发,Mixin混入等。WePY发布的第一个版本是2016年12月份,也就是小程序刚刚推出的时候,到目前为止,WePY已经发布了52个版本, 最新版本为1.7.2;

美团团队开源的一款使用 Vue.js 开发微信小程序的前端框架。使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力。mpvue在发布后的几天间获得2.7k的star,上升速度飞起,截至目前为止已经有13.7k的star;

京东凹凸实验室开源的一款使用 React.js 开发微信小程序的前端框架。它采用与 React 一致的组件化思想,组件生命周期与 React 保持一致,同时支持使用 JSX 语法,让代码具有更丰富的表现力,使用 Taro 进行开发可以获得和 React 一致的开发体验,同时因为使用了react的原因所以除了能编译h5, 小程序外还可以编译为ReactNative;

彩民之家高手论坛 10彩民之家高手论坛 11

跨端框架,一方面要考虑框架提供的通用api跨端支持,同时还要考虑不同端的特色差异如何兼容。毕竟每个端都会有自己的特色,不可能完全一致。

离线包加载

离线包加载,常见的Hybrid App通过webview加载H5页面,前端页面都是放在服务器端。虽说保证了灵活性。但是加载性能收网速影响大。页面切换白屏时间长。小程序离线包的加载方式。一次性加载所有的前端资源到本地再解压。大大提升了用户体验。不过微信官方为了防止下载离线包的时间过程,也严格限制了小程序包的体积。(分包加载情况下子包大小不能超过2M,也就是初次打开加载的资源不能超过2M)

摘要: 对比小程序框架。

之前曾有友商掀起一番真跨端和伪跨端之争,通过本次Demo实测,这个争论可以盖棺定论了。

wepy

wepy应该算是最早发布的小程序开发框架,提供了类vue.js的语法风格和特性,现阶段应该也是应用最广泛的框架吧。我开发的几个小程序也都是采用了wepy这个框架。我先来说说当初为什么选择这个框架的原因吧。

  1. 类Vue.js的语法风格,适合我们团队原有的的技术栈
  2. 支持组件化(当时微信官方的API还不支持组件化)
  3. 支持加载外部npm包
  4. 支持ES6的写法

前期使用wepy的过程中,wepy自带bug。不过好在开发者响应及时,基本上都能覆盖大部分场景。

但是有个最大的坑点就是,wepy组件的实现方式。组件使用的是静态编译组件,即组件是在编译阶段编译进页面的,每个组件都是唯一的一个实例。 多个组件共享同一个数据。并且静态编译组件。导致组件A,在页面A和页面B被引用,会copy两份代码到页面A和页面B内部。导致拆分组件并没有对包的体积有任何减少。后期微信官方API支持组件化编程后,我们逐步把一些比较核心,体积较大的组件用原声API重构了。

request请求

wepy对wx.request做了接受参数的修改,值得一提的是它提供了针对全局的intercapter拦截器。

彩民之家高手论坛 12

拦截器

彩民之家高手论坛 13

taro对request进行了二次封装,可以使用Taro.request发起网络请求,支持 Promise 化使用。

彩民之家高手论坛 14彩民之家高手论坛 15彩民之家高手论坛 16

mpvue没有对request做特殊优化,与原生相同,可以自己根据需要进行封装

最后补充跨端案例:

小程序开发实践总结

2018/08/22 · 基础技术 · 小程序

原文出处: Darko   

从微信发布小程序以来,各大公司纷纷跟进都想从微信这个流量池里捞一杯羹。我司也不例外,我们整个前端团队这半年来基本上都是在开发小程序。前前后后也开发了四五个小程序了。总觉得要留下点什么,既是记录那些年我们踩过的坑,也是希望大家别再掉坑。

列表渲染

在列表渲染上三者也分别有不同的应用方法

wepy当需要循环渲染WePY组件时(类似于通过wx:for循环渲染原生的wxml标签),必须使用wepy定义的辅助标签。

彩民之家高手论坛 17

mpvue使用v-for与vue一致,只是需要注意一点,嵌套列表渲染,必须指定不同的索引!

彩民之家高手论坛 18

taro的列表循环用法基本与react相同,有一点需要注意,在 React 中,JSX 是会编译成普通的 JS 的执行,每一个 JSX 元素,其实会通过 createElement 函数创建成一个 JavaScript 对象(React Element),因此实际上你可以这样写代码 React 也是完全能渲染的:

彩民之家高手论坛 19

但是 Taro 中,JSX 会编译成微信小程序模板字符串,因此你不能把 map 函数生成的模板当做一个数组来处理。当你需要这么做时,应该先处理需要循环的数组,再用处理好的数组来调用 map 函数。例如上例应该写成:

彩民之家高手论坛 20

  • taro:H5端实现了大部分微信的API,App端和微信的差异比较大。
  • uni-app:组件、API、配置,大部分在各个端均已实现,个别API有说明在某些端不支持。可以看出uni-app是完整在H5端实现了一套微信模拟器,在App端实现了一套微信小程序引擎,才达到比较完善的平台兼容性。
  • chameleon:非常常用的一些组件和API在各端已经实现,这部分的平台差异较少。但大量组件和API需要开发者自己分平台写代码。

渲染层和逻辑层分离

彩民之家高手论坛 21
相比于之前常见的Hybrid的方案,小程序使用了双线程模型:小程序的渲染层和逻辑层是是分开的,逻辑层通过JSCore来解析和执行,渲染层是通过webview来渲染。之前的常见Hybrid离线包的方案大多使用webview同时实现页面的渲染和js的解析。这样做的的结果就是隔离了js的runtime,在js代码中无法操作webview中的DOM对象和BOM对象。Js无法做任何和页面渲染有关的操作。只能通过setData把数据从JsCore传递到webview。

独立的JS运行环境,相比于webview同时处理页面的渲染和JS的执行带来了一些好处:

  1. js无法动态的在页面插入节点和干预页面的渲染,解决了安全和管控的问题,否则小程序的上线审核就变得毫无意义。
  2. 渲染层和逻辑层的分离,减轻了webview的压力,js的执行和页面的渲染可以并行,不会出现js执行卡主页面渲染的情况。
  3. 多个页面可以共享一个JS运行环境,数据很方便的共享,整个小程序的生命周期共享同一个上下文,接近App的体验。

坏处在于:

  1. 多了很多webview和JSCore数据传输的消耗,数据需要序列化成字符串格式进行传输。

众所周知如今市面上端的形态多种多样,手机Web、ReactNative、微信小程序, 支付宝小程序, 快应用等,每一端都是巨大的流量入口,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。但面对目前市面上成熟的小程序第三方框架如何针对自己的需求进行选择也是一个麻烦事,本文针对当前市面上的三大转译框架进行一个综合对比,希望能对大家的技术选择有所帮助,如有哪里不妥的地方希望大家指正。

测试结果说明:

微信小程序主流框架对比

  • wepy
  • mpvue
  • Taro

生命周期

同为vue规范的mpvue和wepy的生命周期和各种方法不尽相同。

wepy生命周期基本与原生小程序相同,再此基础上糅合了一些vue的特性; 对于WePY中的methods属性,因为与Vue中的使用习惯不一致,非常容易造成误解,这里需要特别强调一下:WePY中的methods属性只能声明页面wxml标签的bind、catch事件,不能声明自定义方法,这与Vue中的用法是不一致的。

彩民之家高手论坛 22彩民之家高手论坛 23彩民之家高手论坛 24

  • taro:官方提供了taro ui,支持小程序(微信/支付宝/百度)、H5平台,不支持App,详见
  • uni-app:官方提供了uni ui,可全端运行;uni-app还有一个插件市场,里面有很多三方ui组件,详见
  • chameleon:官方提供了cml-ui扩展组件库,可全端运行,但组件数量略少,详见

Fundebug经授权转载,版权归原作者所有。

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

  • 原文:小程序第三方框架对比 ( wepy / mpvue / taro )
  • 公众号:前端小苑

不过横评这件事,要想做完善,其实非常花费时间。不是只看文档就行,它需要:

工具

所有多端框架均支持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框架的跨端问题,评测结果如下:

尤其是与原生微信小程序开发相比性能怎么样,这是大家普遍关心的问题。

各个待评测框架,是否真得如宣传的那样,一次开发、多端发布?

  • taro:提供了js环境变量判断和统一接口的多端文件,可以在组件、js、文件方面扩展多端,不支持其他环节的分平台处理。
  • uni-app:提供了条件编译模型,所有代码包括组件、js、css、配置json、文件、目录,均支持条件编译,可不受限的编写各端差异代码。
  • chameleon:提供了多态方案,可以在组件、js、文件方面扩展多端,不支持其他方式的分平台处理。

我们将上述仿微博App依次发布到各平台,验证每个框架在各端的兼容性,结果如下:

开发一次,到处运行,是每个程序员的梦想。但现实往往变成开发一次,到处调错。

技术支持和社区活跃度

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

目前看,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两框架自身的学习门槛

周边生态

一个底层框架,其周边配套非常重要,比如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)的百度指数:

彩民之家高手论坛 25image

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。

综合以上信息,本项的最终评测结论:uni-app > taro > chameleon > mpvue > wepy原生微信小程序

上周,Taro 团队发布了一篇《小程序多端框架全面测评》,让开发者对业界主流的跨端框架,有了初步认识。感谢 Taro 团队的付出。

平台 微信原生 wepy mpvue taro uni-app chameleon
微信小程序 ⭕️ ⭕️ ⭕️ ⭕️ ⭕️ ⭕️
支付宝小程序 ⭕️ ⭕️ ⭕️
百度小程序 ⭕️ ⭕️ ⭕️
头条小程序 ⭕️ ⭕️ ⭕️
H5端 上拉加载/下拉刷新失效 ⭕️ 上拉加载/下拉刷新失效
App端 上拉加载失效 ⭕️ 列表无法滚动,无法测试上拉加载/下拉刷新

跨端框架基本都是compiler runtime模式,引入的runtime是否会降低运行性能?

但是仅有上面的测试还不全面,实际业务要比这个测试例复杂很多。但我们没法开发很多复杂业务做评测,所以还需要再对照各家文档补充一些信息。由于每个框架的文档中都描述了各种组件和API的跨端支持程度。我们过了几家的文档,发现各家基本是以微信小程序为基线,然后把各种组件和API在其他端实现了一遍:

我们依然以上述仿微博小程序为例,测试2个容易出性能问题的点:长列表加载、大量点赞组件的响应。

我们 uni-app 团队投入一周完成了这个深度评测,下面我们就分享下,实际开发不同框架的测试例遇到的问题,和最终的测试结果。

  • 真实的动手写多个平台的测试demo,比较各个平台的功能、性能,它们的实际情况到底是不是如文档宣传的那样?
  • 真实的学习每个框架,了解它们的学习曲线,在实际开发中遇到问题时,感受它们的文档、教程、社区生态和技服能力到底怎么样?
  • ⭕ 表示支持且功能正常,❌ 表示不支持,其它则表示支持但存在部分bug或兼容问题
  • wepy 2.0 宣称版已支持其他家小程序,本测试基于wepy官网指引安装的wepy-cli默认版本为1.7.3,尚不支持多端
  • chameleon尝鲜版宣称支付宝、百度小程序,本测试基于chameleon官网指引安装的chameleon-tool默认版本为0.1.1,尚不支持其它小程序

通过这个简单的例子可以看出,跨端支持度测评结论:uni-app > taro > chameleon > mpvue >wepy原生微信小程序

版权声明:本文由彩民之家高手论坛发布于前端知识,转载请注明出处:跨端开拓框架深度横评彩民之家高手论坛