今天前来专栏分享的极客,是腾讯微信支付团队。小程序公测一个月时,微信支付团队开源了小程序上的组件化开发框架 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.postMessageiOS 中基于 window.webkit.messageHandlers.invokeHandler.postMessageAndroid 中基于 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公众号,共筑微信生态。