【小程序云函数】数据周期性更新&数据预拉取踩坑

2,483 阅读5分钟

前言

为增强小程序在弱网下的使用体验,开始对小程序数据周期性更新数据预拉取这两个官方提供的功能的做一下可用性体验测试。

数据周期性更新: 周期性更新能够在用户未打开小程序的情况下,也能从服务器提前拉取数据,当用户打开小程序时可以更快地渲染页面,减少用户等待时间,增强在弱网条件下的可用性

数据预拉取: 预拉取能够在小程序冷启动的时候通过微信后台提前向第三方服务器拉取业务数据,当代码包加载完时可以更快地渲染页面,减少用户等待时间,从而提升小程序的打开速度 。

功能开通

主要开启入口,登录小程序MP管理台 -> 开发 -> 开发管理 -> 开发设置 (然后拉到最后)。

选择开启后会弹出管理员扫码弹窗。扫码之后会让你选择使用业务域名还是云函数来调用此功能。(下面我们以开通周期性更新作为流程案例)

业务域名

2020年11月增加了新规定,个人用户在开通【数据周期性更新/数据预拉取】功能只能选择云函数(在此之前还有一个https域名的选项),而企业用户可选择业务域名和云函数。 业务域名:需要经过icp认证与企业有业务关联的域名。

云函数

因为还处于摸索阶段,我们就不劳烦后端和运维大哥。这两个功能都统一走云函数这个模块。 在选择使用云函数开发周期性更新后,会有下面这个弹窗提示你选择环境ID和云函数名,用以部署周期性更新。

正常来说选择了云函数并提交后就算是部署了周期性更新了,但是在此之前,你得开通云开发并且创建云函数。

开通云开发

开通云开发两种方式

1.重新开启一个小程序项目

在MP控制台—> 开发 —> 云开发 里开通功能,然后本地新建项目

勾选【小程序·云开发】就能快速构建带有云开发模板的项目。

2.在已有的项目上添加云开发。

首先你要在已有项目中的project.config.json文件中添加字段

"cloudfunctionRoot": "cloudfunction/",

增加这个路径之后,在小程序编辑器的目录中右键cloudfunction文件夹(如果编辑器没有新建就手动在根目录建一个同名文件夹)选择新建Node.js 云函数。 然后你就有了一个这样的文件模板。如果要运行本地测试还需要在这个目录下运行npm i (这里推荐yarn)

新建&部署

新建testWeakNet云函数之后

// testWeakNet.js
const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})
console.log('当前环境', cloud.DYNAMIC_CURRENT_ENV)
// 云函数入口函数
exports.main = async (event, context) => {
  console.log(event, context)
  const wxContext = cloud.getWXContext()
  return {
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}

写好代码之后右键选择要部署的云函数,选择【创建并部署】之后点击小程序开发工具左上角的云开发然后在云开发tab新建同名云函数。

最后配置好云开发的状态:

调用

周期性更新与预拉取都是共用wx.getBackgroundFetchData这个api,唯一区别是fetchType。预拉取使用pre,周期性更新使用periodic。而wx.setBackgroundFetchToken看官方文档的解释:

第一次启动小程序时,调用 wx.setBackgroundFetchToken() 设置一个 TOKEN 字符串,可以跟用户态相关,会在后续微信客户端向开发者服务器请求时带上,便于给后者校验请求合法性。

可以看做是调用这个功能的初始化类似于cloud.init()

// app.js
cloudFunction() {
    // 云函数初始化
    if (!wx.cloud) {
        console.error('请使用 2.2.3 或以上的基础库以使用云能力');
    } else {
        wx.cloud.init({
            env: 'xxxxx-xxxxx', // 想要请求切换哪个云环境,就用哪个的
            traceUser: true,
        });
    }
    
    wx.setBackgroundFetchToken({
        token: 'weakNet'
    });
    // 弱网数据拉取 256kb 限制 fetchType ? periodic 周期数据更新 / pre 预拉取
    wx.getBackgroundFetchData({
        fetchType: 'pre',
        success(res) {
            const fd = JSON.parse(res.fetchedData);
            console.log('pre_fetch success', fd);
        },
        fail(e) {
            console.log('pre_fetch fail', e);
        },
        complete(e) {
            console.log('pre_fetch complete', e);
        }
    });
},

调试

数据周期性更新:

微信开发者工具 -> 工具 -> 拉取周期性缓存数据 选择之后控制台会出现缓存的提示

数据预拉取: 开发工具右边的详情中打开本地设置,勾选【启用数据预拉取】 设置成功后在控制台可以看到拉取的云函数回调

注意事项

不管是数据预拉取还是数据周期性更新,有以下几点注意事项

1. 在获取的缓存数据fetchData 的格式都是 JSON 字符串
2. 缓存数据不能大于256KB
3. 云函数内不能调用云函数
4. 云函数的部署和本地代码要及时清除缓存

关于第三点【云函数内不能调云函数】 原因: 我的预拉取数据云函数testWeakNet 中调取了同环境下的request云函数,但是返回的res没有把request的结果转出来,而是直接吧res赋值的函数字面量字符串化作为返回发到了客户端

常见报错类型:

  1. 错误码:-10007。没有在MP开启功能 & 没有设置token
  2. 错误码:-501003。当前周期性数据: {"errcode":-501003,"errmsg":"Request exceeded the limit"}。这有几种可能。当前云环境处于限制状态处于隔离期,或者请求超过当日限制数。

参考文档

1.微信小程序|周期性更新:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/background-fetch.html

2.微信小程序|数据预拉取:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/pre-fetch.html

3.微信小程序|我的第一个云函数:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/getting-started.html

原创不易~如果看到这里对您有点帮助请给个赞啦,嘻嘻