云原生微信小程序开发实战读书笔记-5

数据预取也叫数据预加载,顾名思义,这项能力能提前加载未来要使用的数据,然后缓存到本地。这样一来,你在使用这些数据时就省去了加载时间,能更快地把页面展示给用户,在很大程度上提升用户体验。

小程序提供的两种数据预加载能力

这两种能力的底层原理和设置方法类似,只是应对的使用场景不同。

周期性更新和数据预拉取

周期性更新是指: 在用户未打开小程序的情况下,微信客户端从服务器拉取数据,并且缓存到小程序本地,用户下次打开小程序时就已经有了预加载数据,进而能够快速地将页面展示给用户。

这项能力主要解决当用户设备处于弱网环境下,造成的网络请求耗时过长,以及用户长时间等待过长造成的用户流失。所以周期性更新预加载的资源通常是小程序首屏的数据。

数据预拉取的执行时机与周期性更新不同,是在小程序冷启动阶段执行数据的预加载(小程序另外的启动情况是热启动)。

  • 冷启动是指: 用户首次打开,或小程序销毁后被用户再次打开时,小程序需要重新加载启动的情况。

  • 热启动是指: 用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态的情况。

打开小程序后,进入冷启动还是热启动状态的决定性条件是小程序是否被销毁,那么小程序什么场景下会被销毁?一种场景是小程序退回到后台以后超过一定时间未被唤醒到前台;另一种场景就是当小程序占用的内存过高。

应对弱网的周期性更新

小程序周期性更新的配置流程里,你需要关注这三个步骤:

  1. 配置预加载数据的请求地址。

  2. 在第一次启动小程序时,将自定义登录态同步给微信客户端,请注意是微信客户端而不是微信服务器。

  3. 在用户再次启动小程序时,直接读取预加载的数据。

首先是配置预加载数据的请求地址,你可以在微信小程序的管理后台中找到“开发”-“开发设置”=“数据周期性更新”:

Drawing 0.png

点击开启后,你就会开始配置请求地址,这个地址就是需要被预加载的数据来源,微信服务器会从这个地址拉取所需的预加载数据。

在管理后台开启了周期性更新之后,第二步就是把小程序的自定义登录态同步给微信客户端,同步的方法是使用小程序 SDK 提供的wx.setBackgroundFetchToken API,语法请看下面这段代码:

App({
  onLaunch() {
    // 第1步:从storage中取出自定义登录态
    const token = wx.getStorageSync('<token-key>')
    // 第2步:将登录态同步给微信客户端
    wx.setBackgroundFetchToken({
      token
    })
  }
})

这段代码是假设小程序已经登录了,这时候本地的 storage 中已经存在自定义登录态,然后从本地缓存中取出并同步给微信客户端。

经过上面两个步骤,你就已经成功启动了周期性更新,微信客户端会每隔 12 小时发送一个请求,请求的目标就是你在第一步配置的地址,然后将获取到的数据(也就是 HTTP 请求的 Body 数据缓存到本地)。之后,当用户再次打开小程序时,就能获取这些缓存数据,获取的方法是借助小程序 SDK提供的wx.getBackgroundFetchDataAPI,请看以下代码片段:

App({
  onLaunch() {
    wx.getBackgroundFetchData({
      fetchType: 'periodic',
      success(res) {
        console.log(res.fetchedData) // 缓存数据
        console.log(res.timeStamp) // 客户端拿到缓存数据的时间戳
      }
    })
  }
})

定时拉取数据的时间间隔( 12 小时)是怎么实现的?

周期性更新并不是一个定时任务,而是一个任务队列,简单讲就是一个个顺序排列的任务,只有当前面的任务被执行成功之后,后面的任务才会被执行。小程序的周期性更新的计时规则是: 只有当一次更新数据成功之后,才会再次向任务队列中放入一个 12 小时执行的新任务。

这套机制与定时任务的区别在于: 定时任务一般是不管执行结果的,只要任务被执行了不论成功还是失败,都会在精准的 12 小时之后执行下一个任务。而任务队列通常是阻塞式的,也就是只有当前面的任务执行成功,才会继续执行后面的任务。所以任务队列通常具备重试机制,即某个任务失败后重新尝试执行,这样做可以提高每一次更新的成功率。

根据上面的步骤,小程序周期性更新的完整流程可以描述为下面这张图:

Lark20201204-183844.png

应对冷启动的数据预拉取

除了执行时机不同以外,数据预拉取跟周期性更新在配置的方法和使用的流程上都非常接近。你需要关注的仍然只有三点:

  1. 配置预加载数据的请求地址。
  2. 在第一次启动小程序时,将自定义登录态同步给微信客户端。
  3. 在用户再次启动小程序时,直接读取预加载的数据。

二、三步的操作方法跟周期性更新完全一样,使用的 API 也是同一份。唯一的区别就是第一步的配置入口不同,数据预拉取的配置入口在小程序管理后台的“开发”-“开发设置”-“数据预拉取”中,你会找到下面这张图所示的配置:Drawing 2.png

跟周期性更新的配置一样,你可以填写开发者服务器的一个接口地址,也可以填写一个云函数。

配置和使用流程一致只是表象,数据预拉取与周期性更新的技术原理并不完全相同。数据预拉取并没有每隔 12 小时轮询一次的机制,而是在用户打开小程序时,如果小程序时冷启动,这时候会发起数据预拉取的任务。冷启动结束以后小程序便可直接获取预拉取的数据,完整的流程如图所示:

Lark20201204-183859.png

小程序的数据预取能力其实是借微信客户端完成的,包括预加载数据的网络请求和数据的缓存,而小程序最终只是从微信客户端的缓存中读取已有的数据而已。