聊聊微信小程序及其框架

为什么是微信小程序

微信很早就有一套专用的JS-SDK在微信客户端上面使用,其开放了录音、二维码、地图、支付等几十个 API,能够支持微信服务号的运转,当时大部分支付、扫码等功能的对接方都是这样的服务号。但是在 2016 年 1 月 11 日微信之父张小龙表示服务号还不够优秀,微信正在研究一个新的服务形态,起名叫做“微信小程序”。在 2017 年 1 月 9 日,第一批微信小程序低调上线,而选择这一天也是为了向 iPhone 1 代的发布致敬。

很快,微信小程序依靠微信的庞大用户量迅速的占领了市场,其他各个大厂见势相继效仿,但是从目前来看它们都很难和微信小程序再抗衡了——不管是用户数量还是开发者数量。这倒也不太奇怪,这种行业往往都是快鱼吃慢鱼不是大鱼吃小鱼,emmm…不过背靠腾讯的微信也不能说是小鱼吧。

为什么要写微信小程序

首先想说的是,微信小程序的生态是比较混乱的,开发起来有一点难受,有不少情绪比较激动的开发者直接说微信小程序就是“s**t”,我也能够理解其中的一大部分感情。

我从大二参加微信举办的第一届大学生微信小程序大赛到现在已经有 3 年了,这期间虽然不是一直在开发小程序,但是每年都会或多或少因为课程或者是项目的原因接触小程序开发,所以对微信小程序还是有一定的了解的。

小程序非常不好写。我觉得有以下几个方面的原因:

  1. 一个页面(Page)拆成四个文件这样分散的组织形式让我觉得有点难受,有的人可能会说这是关注点分离,但是我觉得 Vue 在单文件内拆成多个部分的形式可能更好一点,一个重要的事情值得注意,关注点分离不等于文件类型分离。而且你说一个叫做page的页面,它下面的四个文件名是叫page.wxml好还是叫index.html好呢?
  2. 微信开发者工具非常不好用,首先它很占内存,内存小的机器上运行微信开发者工具一段时间后会出现奇奇怪怪的问题,因为遇到的次数有点多也没有特别记得,在这里也说不出来了。
  3. 因为在微信的生态里面,处处都要依照微信的规矩来进行开发或者运维(这倒也没办法),用某某接口需要是某某类目的小程序,需要有某某资质的主体等等……申请接口、申请上线等种种流程都十分繁琐。
  4. 官方文档有些混乱,而且最近两三年内没有进行过较大的更新改进。

但是有的时候又不得不写它,因为它对用户更加友好。如果换作是我的话,我也不会为了去餐厅点餐或者是在奶茶店买奶茶专门下载一个 App,为了扫健康码就更不会。微信小程序就是为了替代微信服务号这样的“用完就关”的应用场景的,开发的时候把它当作微信服务号 2.0 来开发就好了,不要提高自己的心理预期以为自己是在开发一款 App。这样想的话,开发起来就会好接受多了。

小程序框架浅析

逻辑层和渲染层

微信小程序通过微信客户端(Native)这一桥梁向外界服务器发送请求和接受响应、调用手机本地接口(拍照、上传文件等)。小程序分为了渲染层和逻辑层,小程序页面的 WXSS、WXS 和 WXML 运行在渲染层,而 JS 运行在逻辑层。WXS 是专门给小程序推出的一个脚本语言,是 JS 的子集,运行在渲染层执行一些简单的数据处理任务,据官方文档说使用 WXS 在 Android 上没有太多性能提升,但是在 iOS 上用其执行相关任务能加速 2~20 倍。

微信小程序的渲染层与逻辑层也通过 Native 进行通信,比如渲染层将触发的事件传输到逻辑层,逻辑层将更新的数据传输到渲染层等等。可以看到上面这张图里渲染层分了很多个 Webview,其中每个 Webview 都代表了一个小程序页面。

WXML 文件其实是标识了页面的元素及其相互关系,在微信小程序的编译过程中,WXML 文件会被编译成为 JS 对象用来在渲染层维护一个虚拟的 DOM 树。通过与逻辑层的数据进行组合,形成一个数据和结构都完整的虚拟 DOM 树用以渲染。每次在逻辑层调用 setData 方法时,逻辑层都会将这个消息传输到渲染层,渲染层通过对比发来的数据与之前的数据,将有差异的数据应用到 DOM 树上,从而进行更新渲染。

目前市面上有许多的小程序开发框架,如 Taro、Uni-App、mpvue、WePY 等,有实验显示使用小程序框架进行开发会使得小程序性能提升,其中很大一部分原因就是开发框架会对 setData 的调用进行优化,减少逻辑层和渲染层的实际通讯次数,从而提升性能。

而采用渲染层和逻辑层的架构主要是为了阻断页面渲染和逻辑处理,从而加强监管、提升性能。

小程序页面生命周期

从微信小程序官方文档上面的生命周期图示(方便起见,我把纵向的长图拆成了左右两个部分)可以看得很清楚,逻辑层与渲染层分别进行初始化。

  1. 逻辑层执行完 onLoad 和 onShow 两个生命周期函数之后,等待渲染层初始化完成的通知;
  2. 逻辑层收到通知之后,将初始数据传输给渲染层,渲染层拿到数据进行首次渲染之后再次通知逻辑层,让其执行 onReady 生命周期函数;
  3. 执行完 onReady 函数之后,小程序就处在 Active 状态了;
  4. 如果小程序在激活状态下被最小化到微信的后台或从后台被唤起,则会调用 onHide 和 onShow,如果在激活状态被关闭,则会调用 onUnload (一般不会用到)。

小程序从后台被唤起时的启动叫做热启动,第一次打开或者距离上一次打开已经过去了足够长的时间时叫做冷启动。他们进入页面生命周期的位置不同,开发的时候需要格外注意一下。

我自己的小程序开发方法

开发微信小程序有许许多多的方式,最原始质朴的方式就是直接使用微信开发者工具进行编码和调试,这是我在大二的时候使用的方法。我已经很久没有用过这种方法了,但是它至今仍然给我很不好的回忆,究其根本主要是因为 IDE 实在是太难用了。

后来使用 WebStorm 来进行微信小程序编码,但是发现我自己的笔记本电脑(18 年老电脑了)同时带 WebStorm 和微信开发者工具两个“重型” IDE 实在是有点吃不消,遂作罢。

后来接触到了 gulp 这个前端工程化工具,可以让编码过程更加自由,尤其是能够使用 sass 等 css 预处理器,让我觉得开发起来清爽了很多。目前我是用VS Code进行编码,同时使用了minapp, Live Sass Compiler这两个插件,能够原地使用 sass,也没有增加过多的复杂性,很符合我自己的“编码哲学”hhhh。

我在写代码的时候一直觉得奥卡姆剃刀原理是真理,可以不要的就一定不要。这样的想法使得我在之前的开发中从没有想过用小程序开发框架,“一次编码自动构建多个平台的小程序”,我需要开发的只有“微信小程序”这一个而已,不需要增加那么多的复杂性。

但是最近越来越受不了小程序复杂的设计了,尤其是写惯了 Vue 再来写小程序,简直就和降智了似的。

之后我应该会看一些小程序框架的文档,先从 Uni-App 和 WePY 这两个开始吧。Uni-App 是用 Vue 语法开发小程序的框架,支持一键生成多端小程序。而 WePY 则是微信官方推出的小程序开发框架,仅支持微信小程序。这也算是立了 flag 吧。

作者

PowerfooI

发布于

2021-01-21

更新于

2024-08-04

许可协议

评论