微信小程序开发总结

近期发布了我的v1.0.0的“e生活助手”小程序,主要目的是从自身需求出发,利用业余时间编写一个感兴趣的小程序,主要是菜谱搜索,用到的是聚合数据的接口;天气接口 以及 每日寄语 功能;三者接口方面就不一一赘述了,哈哈,很曲折。

通过开发的这个小程序,对小程序开发的流程及相关技术相对比较熟悉,在开发过程中也总结了一些心得经验、了解一些小程序文档上没有的东西、踩了一些坑。所以想着结合自己的情况和前辈们的小程序见解,记录下来,并借此将小程序开发的相关知识进行梳理。

1. 微信小程序基本知识与概念

______________________________

微信小程序开发,入门算是非常简单,只要看官文文档即可小程序简易教程。如何申请小程序账号,如何开发自己第一个小程序,如何发布,这一系列hello world操作官方文档都有手把手教学。小程序开发的每个步骤,提供的能力文档里都有,个人觉得,做小程序开发,有事没事都看下文档,因为小程序更新比较快速,同时一些细小的能力我们可能会漏掉,所以多看文档。

1.1小程序项目的文件目录结构

______________________________

文件目录结构很灵活

除了app.json必须位于根目录下,其他文件随意,并且都可以删。并且页面文件可以放到如何位置,只要在app.json中的pages中配置了就可以。可以说是很灵活。你还可以多个页面放在同个文件夹下。

全局配置文件app.json

对于一个小程序项目而言,最重要的文件是app.json,它也是开发工具识别一个文件夹是否为小程序项目的标识。当使用开发者工具创建一个项目是,如果选择的是空文件夹,它会创建一个新的项目。如果是一个有文件的文件夹,它会看该文件夹中是否有app.jon文件,如果有,则它会认为是一个小程序项目,则会打开该项目,如果文件夹中没有app.json文件,则提示无法创建项目。

app.json必须放置于项目的根目录下,它是小程序项目的全局配置文件。在小程序代码包准备完成进行启动后(下文会详细介绍小程序从用户点击打开小程序到小程序销毁的整个过程),会先读取app.json文件,进行小程序的初试化,比如初始化整个小程序外框样式,获取首页页面地址等。

其实小程序就是微信提供的一个容器,各个页面就在这个容器里加载运行销毁。

下面介绍下小程序的全局配置选项:

注意:
  • 所有配置项key必须使用双引号括起来,value值为字符串类型的也必须使用双引号,不支持单引号
  • 因为小程序功能迭代非常迅速,基础库版本更新也很快

pages

在app.json中,pages选项是必须配置的。该配置项注册了小程序所有页面的地址,其中每一项都是页面的 路径+文件名 。配置的字符串其实就是每个页面wxml路径,去掉.wxml后缀。因为框架会自动去寻找路径下.json、.js、.wxml、.wxss四个文件进行整合。也就意味着.json、.js、.wxss这三个文件的文件名必须要和.wxml的一致,否则不生效。所以一个页面至少必须得有.wxml文件。

总结:
  • 页面的.json、.js、.wxss文件必须与.wxml文件同名,否则不生效
  • 每个页面都必须pages下注册,没有注册的页面,如果不访问,编译能通过,一旦试图访问该页面则会报错
  • 可以通过在pages下添加一个选项快速新建一个页面,开发工具会自动生成对应的文件.

window

该配置项用于配置小程序的全局外观样式,具体请查阅文档。这里重点提一下两个比较实用的

tabBar

该选项可以让我们轻松实现导航栏tab效果,不过有个不足就是跳转可操作性非常低。就是每个tab只能跳当前小程序页面,不同跳到其他小程序。如果需要跳到其他小程序,还需自己封装个组件。
networkTimeout
这是网络请求超时时间,可以设置不同类型请求的超时时间,比如wx.request、wx.uploadFile等。其实很多时候我们都会忽略这个选项,小程序默认是60s超时,但我们应该手动设置更低的值,因为我们的接口一般都会在10s内完成请求(如果超过10s,那你是时候优化了),所以如果网络或者服务器出问题了,那么会让用户等60s,最后还是失败,这对用户很不友好,还不如提前告诉用户,现在出问题了,请稍后再试。
前段时间由于公司服务器网关出现了点小问题,导致有些请求连接不上,出现大量连接超时。通过之前添加的错误信息收集插件(这个是性能优化,下文有讲到)看到了很多接口返回time-out 60s。让用户等了60s还是失败,这不友好。所以这个超时时间一般设置15s-30s比较好。
debug
是否开启debug功能,开启后查看更多的调试信息,方便定位问题,开发阶段可以考虑开启
functionalPages
这个是结合插件使用的,因为微信小程序插件有很大限制,插件里提供的api很有限,wx.login 和 wx.requestPayment 在插件中不能使用,如果需要获取用户信息和进行支付,就必须通过插件提供的功能也实现。当你的小程序下的插件启用了插件功能也时,必须设置该选项为true.
小程序插件必须挂载在一个微信小程序中,一个小程序也只能开通一个插件。当你小程序开通的插件启用了插件功能也时,必须设置该选项为true
plugins
当小程序使用了插件就必须在这里声明引入。小程序自身开通的小程序不能在本身应用.

1.2 小程序启动与生命周期

下面来说说小程序从用户点击打开到销毁的整个过程。用图说话更清晰,特地画了个流程图:
小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。 假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台态的小程序切换到前台,这个过程就是热启动;冷启动指的是用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动。
上面的流程图包含了所有内容,但毕竟文字有限,接下来详细说下几个点。
  1. 小程序会先检测本地是否有代码包,然后先使用本地代码包进行小程序启动,再异步去检测远端版本。这就是小程序的离线能力,相对于H5,这是优点,能加快小程序启动速度。
  2. 当本地有小程序代码包时,会异步去请求远端是否有最新版本。有则下载到本地,但该次的启动还是会用之前的代码。所以当我们发布了最新的版本,需要用户两次冷启动,才能使用到最新版本。如果想要用户一次冷启动就可以使用到最新版本,可以使用小程序提供的版本更新API更新。代码如下,只要在app.js的onShow函数加上以下代码,每次小程序有更新,都会提示用户更新小程序。不过这个每次提示更新,一定程度上影响用户体验。如果结合后端配置,每次进来读取配置,就可以实现根据需要是否进行该版本的更新,比如一定需要用户更新才能使用的,那就使用强制更新。对于一些小版本,就不需要使用这个强制更新。

2 重点介绍几个组件

2.1 web-view

web-view的出现,让小程序和H5网页之前的跳转成为了可能。通过把H5页面放置到web-view中,可以让H5页面在小程序内运行。同时在H5页面中也可以跳转回小程序页面。可以说是带来了很大的便利,但同时由于web-view的诸多限制,用起来也不是很舒服。
  1. 需要打开的H5页面必须在后台业务页面中配置,这其中还有个服务校验。另外H5页面必须是https协议,否则无法打开
  2. web-view中无法在页面中调起分享,如果需要分享,比如跳回小程序原生页面
  3. 小程序与web-view里H5通信问题。小程序向web-view传递,不敏感信息可以通过页面url传递。如果是敏感信息比如用户token等,可以让服务端重定向,比如请求服务端一个地址,让他把敏感信息写在cookie中,再重定向到我们的H5页面。之后H5页面就可以通过在cookie中拿这些敏感数据了,或者http-only,发送请求时直接带上。
  4. 每次web-view中src值有变化就会重新加载一次页面。所以个src拼接参数时,需要先赋值给个变量拼接好再一次性setData给web-view的src,防止页面重复刷新
  5. 从微信客户端6.7.2版本开始,navigationStyle: custom对组件无效。也就意味着使用web-view时,自带的导航栏无法去掉。
  6. 因为导航栏无法去掉,这里就出现了一个巨大的坑。实现全屏效果问题。如果想要实现H5页面全屏,就是不滑动,全屏显示完所有内容。这时如果你使用width:100%;height:100%,你会发现,你页面底部可能会缺失一段。上图:
因为web-view是默认铺满全屏的,也就是web-view宽高和屏幕宽高一样。然后H5页面这是高度100%,这是相对web-view的高度,也是屏幕高度。但是关键问题:web-view里H5页面是从导航栏下开始渲染的。这就导致了H5页面溢出了屏幕,无法达到全屏效果。
解决方法
这个问题我在前段时间的实际项目碰到过,我们要做个H5游戏,要求是全屏,刚开始我也是设置高度100%。后来发现底部一块不见了。我的解决方法比较粗暴,如果有更好的解决方法,欢迎评论交流。 我的解决方法是:通过拼接宽高参数在H5页面url上,这个宽高是在web-view外层计算好的。H5页面直接读取url上的宽高,动态设置页面的宽高。页面高度的计算,根据上图,很显然就是屏幕高度减去导航栏高度。宽度都是一样的,直接是屏幕宽度。
但问题又来了,貌似没有途径获取导航栏高度。而且对于不同机型的手机,导航栏高度不同。经过了对多个机型导航栏跟屏幕高度的比较。发现了一个规律,导航栏高度与屏幕高度、屏幕宽高比有一定的关系。所以根据多个机型就计算出了这个比例。这解决了95%以上手机的适配问题,只有少数机型适配不是很好。到基本实现了全屏效果。

2.2 scroll-view


当我们要实现一个区域内滑动效果时,在H5页面中我们设置overflow-y: scroll即可。但在小程序中,没有该属性。需要用到scroll-view标签。具体操作实现我们可以查看文件scroll-view
锚点定位在前端开发中会经常用到,在H5页面中,我们会在url后面加上#来实现锚点定位效果。但是在小程序中这样是不起作用的,因为小程序内渲染页面的容易不是一个浏览器,无法实时监听Hash值得变化。但是使用scroll-view,我们可以实现锚点点位效果。主要是使用scroll-into-vie属性具体实现我们直接上代码
scroll-into-view | String | 值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素

2.3 canvas


画布标签,它是原生组件,所以它必须位于屏幕最上边,而且是不能隐藏的。所以如果想要使用canvas动态生成分享照片。那你要设置她的宽高和屏幕一样。要不导出为照片时就会失真。因为这个原因,所以生成分享照片还是有服务端实现吧,照片失真太严重了。

3 formid收集


给用户发送消息对一个小程序是非常重要的,它可以召唤回用户,导量效果非常明显。我们可以通过模板消息想小程序用户发送消息,但前提是我们得获取到openid和formid。用户登录我们即可即可获取到用户openid。而只要用户有点击行为,我们即可获取到formid获取formid。所以说formid是很重要的。我们可以提前收集好formid,在需要的时候给用户推送消息。我们可以个每个button都包上form标签,只要有用户点击行为都可以收集到formid.
我们实现一个formid收集系统,为了尽量减少冗余代码和减少对业务的影响,我们的设计是这样的
  1. 在整个页面的最外层包裹form标签,不是每个button都包裹一个,这样只要是页面中formTpye=submit的button有点击都能获取到formid。
  2. formid保存在全局变量数组中,当小程序切换到后台是一次性发送。
  3. 对于需要实时发送消息的,不添加值全局数组中,直接保存在页面变量中。

4 性能优化相关


从用户打开小程序到小程序销毁,我们可以想想有哪些地方是可以优化的。首先是打开速度。小程序打开速度直接影响了用户留存。在小程序后台,运维中心-监控告警下有个加载性能监控数据,我们可以看到小程序启动总耗时、下载耗时、首次渲染耗等加载相关的数据。而这里的打开速度其实就是小程序的启动总耗时。它包括了代码包下载、首次渲染,微信内环境初始化等步凑。在这一步,我们能做的就是如何加快代码包下载速度和减少首次渲染时间
在小程序呈现给用户之后,接下来如何提高用户体验,增强小程序健壮性的问题了。每个程序都有bug。只是我们没发现而已,尽管在测试阶段,我们进行了详尽的测试。但是在实际生产环境,不同的用户环境,不同的操作路径,随时会触发一些隐藏的bug。这时如果用户没有向我们报告,我们是无法获知的。所以有必要给我们的小程序增加错误信息收集,js脚本错误,意味着整个程序挂掉了,无法响应用户操作。所以对于运行时的脚本错误,我们应该上报。对出现的bug及时修复,增强程序健壮性,提供用户体验。
每个程序都有大量的前后端数据交互,这是通过http请求进行的。因此,还有一个错误信息收集就是接口错误信息收集。对那些请求状态码非2XX、3XX的,或者请求接口成功了,但是数据不是我们预期的,都可以进行信息采集。
通过对小程序运行时脚本和http请求进行监控,我们就可以实时了解我们线上小程序的运行状况,有什么问题可以及时发现,及时修复,极高地提高了用户体验性。

4.1 让小程序更快


让小程序快,主要因素有两个,代码包下载和首屏渲染。 具体可参看下面的网址了。

 

关于作者

tu