乐趣区

WeGeek | WePY 开源框架

今天前来专栏分享的极客,是腾讯微信支付团队。小程序公测一个月时,微信支付团队开源了小程序上的组件化开发框架 WePY,在 Github 上一经发布便受到了众多开发者的追捧,网上搜索「微信小程序 WePY 开源框架资源汇总」尽是网友们自发分享的相关干货。
尽管 WePY 开源框架如今倍受推崇,回忆起开源的初衷,来自微信支付团队的 Gcaufy 还是表示:「WePY 开源框架的对外开源并不是要去分享一个很成功的解决方案,而是我认为这套方案能够解决在小程序开发中遇到的一些实际问题,并且希望能借助外界的力量去帮助一起完善这套方案。」
接下来,让我们一起看看 WePY 开源框架背后的开发故事吧。

如果你有一定的开发经验,会明显感受到小程序的开发十分容易上手——小程序本身提供一些特性如:模块化,模板,数据绑定等,极大地方便了习惯使用 MVVM 框架的用户。但同时,由于运行环境有限,小程序尚不能使用市面上的流行框架。
在几个月的开发历程里,作者 Gcaufy 便一直希望可以设计出一套方案,更大可能地让小程序开发贴近于当下开发习惯,WePY 开源框架应运而生。
WePY 开源框架的原理很简单:通过 WePY 开源框架开发的代码在经过编译后,能生成一份完美运行在小程序端的代码,使得小程序开发更贴近于传统 H5 框架开发,可以像开发 H5 一样支持引入 npm 包,并且支持组件化开发以及支持 JS 新特性等,实现类 Vue 的开发体验。
WePY 开源框架实现小程序的预加载
我们知道,传统的 H5 可以通过预加载来提升用户体验,那么小程序能够实现吗?
答案是肯定的。在小程序中使用预加载,比在 H5 中实现起来更为简单方便,但也更容易被开发者忽视。
传统 H5 在启动时,page1.html 只会加载 page1.html 的页面与逻辑代码,当 page1.html 跳转至 page2.html 时,page1 所有的 Javascript 数据将会从内存中消失。在 page1 与 page2 之间的数据通信只能通过 URL 参数传递或者浏览器的 cookie,localStorge 存储处理。
而小程序在启动时,会直接加载所有页面逻辑代码进内存。即便 page2 可能都不会被使用,在 page1 跳转至 page2 时,page1 的逻辑代码 Javascript 数据也不会从内存中消失。page2 甚至可以直接访问 page1 中的数据。
小程序的这种机制差异正好可以更好的实现预加载。
通常情况下,我们习惯将数据拉取写在 onLoad 事件中。但是小程序的 page1 跳转到 page2,到 page2 的 onLoad 存在一个 300ms ~ 400ms 的延时。如下图:

因为小程序的特性,完全可以在 page1 中预先拿取数据,然后在 page2 中直接使用,这样就可以避开 redirecting 的 300ms ~ 400ms 了。如下图:

对于上述问题,WePY 开源框架中封装了两种概念去解决:
预加载数据
用于小程序中 page1 主动传递数据给 page2,比如 page2 需要加载一份耗时很长的数据。我可以在 page1 闲时先加载好,进入 page2 时直接就可以使用。
预查询数据
用于避免于 redirecting 延时,在跳转时调用 page2 预查询。
WePY 开源框架添加了 onPrefetch 事件,会在 redirect 之时被主动调用,这一改进扩展了生命周期;同时 onLoad 事件也添加了一个参数,用于接收预加载或者是预查询的数据:
// params
// data.from: 来源页面,page1
// data.prefetch: 预查询数据
// data.preload: 预加载数据
onLoad (params, data) {}
WePY 开源框架实现小程序的数据优化
可能有开发者还不了解,其实小程序的视图层与逻辑层是完全分离的,这二者之间的通信全都依赖于 WeixinJSBridge 实现。如:

开发者工具中是基于 window.postMessage
iOS 中基于 window.webkit.messageHandlers.invokeHandler.postMessage
Android 中基于 WeixinJSCore.invokeHandler

数据绑定方法 this.setData() 亦然,于是很容易想到,频繁的数据绑定会不会导致通信的成本大大增加呢?
为了验证 setData() 存在性能问题,微信支付团队做了一个相关测试:动态绑定 1000 条数据的列表进行性能测试,主要针对以下三种情况:

最优绑定: 在内存中添加完毕后最后执行 setData() 操作。
最差绑定: 在添加一条记录执行一次 setData() 操作。
最智能绑定:不管中间进行了什么操作,在运行结束时执行一次脏检查,对需要设置的数据进行 setData() 操作。

经过十次刷新运行测试后得出了以下结果:

从测试结果可以明显看出,实现同样的逻辑,性能数据却相差 40 倍左右。通过分析测试结果,我们可以得知,在开发过程中,应当尽量避免同一流程内多次 setData() 操作。
那么有什么优化方式呢?
采取人工维护肯定能够实现,但当页面逻辑负责起来之后,即便花很大的精力去维护也不一定能保证每个流程只存在一次 setData(),可维护性也不高。因此,WePY 开源框架选择了使用脏检查去做数据绑定优化。
虽然 WePY 开源框架在语法上借鉴了 Vue,原理则是完全不同的。比如 WePY 开源框架使用的是 ng 的脏检查设计,而不是使用的 Vue 的 getter,setter 等。用户不用再担心在流程里,数据被修改了多少次,只用在流程最后做一次脏检查,并且按需执行 setData() 即可。
使用 WePY 开源框架在开发效率上的提升
除了上述基于性能上做出的优化以外,WePY 开源框架也作出了一系列开发效率上的优化。
支持丰富的编译器

js 可以选择用 Babel 或者 TypeScript 编译。
wxml 可以选择使用 Pug(原 Jade)。
wxss 可以选择使用 Less、Sass、Styus。

支持丰富的插件处理
可以通过配置插件对生成的 js 进行压缩混淆,压缩图片,压缩 wxml 和 json 已节省空间等等。
支持 ESLint 语法检查
添加一行配置就可以支持 ESLint 语法检查,可以避免低级语法错误以及统一项目代码的风格。
生命周期优化
WePY 开源框架添加了 onRoute 的生命周期。用于页面跳转后触发。这一优化项是因为小程序中并不存在一个页面跳转事件。onShow 事件可以用作页面跳转事件,但同时也存在负作用,比如按 HOME 键后切回来,或者拉起支付后取消,拉起分享后取消都会触发 onShow 事件。
优化事件传参
原有的传参写法:
<view data-alpha-beta=”1″ data-alphaBeta=”2″ bindtap=”bindViewTap”> DataSet Test </view>
Page({
bindViewTap:function(event){
event.target.dataset.alphaBeta === 1 // – 会转为驼峰写法
event.target.dataset.alphabeta === 2 // 大写会转为小写
}
})
优化后:
<view @tap=”bindViewTap(“1”, “2”)”> DataSet Test </view>
methods: {
bindViewTap(p1, p2, event) {
p1 === “1”;
p2 === “2”;
}
}
更多详情可以参看 WePY 开源框架文档:https://tencent.github.io/wep…。
WePY 开源框架 2.0 计划
目前 WePY 开源框架主要由微信支付团队内相关人员利用业余时间,与几个外部贡献者一起来维护。技术社区中有不少热心的贡献者,不仅自己参与,也会带来了一些新的贡献者力量,不时还会提供一些比较核心的功能。
当被问及「WePY 开源框架 2.0 进度」问题时,微信支付团队表示现已将进入了 WePY 2.0 内测阶段,相信不久后就将与大家正式见面。
「希望 2.0 是一个全新的,对得起开发者的版本。」
了解更多小程序开发相关内容,欢迎微信扫描下方二维码关注微信极客 WeGeek 公众号,共筑微信生态。

退出移动版