在项目外使用数据预拉取与周期性更新,及云函数的使用
[视频] 你好,我是李艺。 上节课我们主要学习了如何劫持Page类对象及setData方法,这节课我们学习如何实现数据预拉取与周期性更新。 首先我们看一个问题,之前我们针对首页的动态数据加载这个节点已经做了两项优化,第一项在App.onLaunch这个节点就开始加载数据,第二点是只加载首页第一次渲染所需要的这一页数据,但是如果用户设备它处于弱网环境下或者是它网速很慢怎么办? 在这种情况下,即使我们再提前加载,再减少数据的加载量,都不能改变我们首页仍然是加载渲染缓慢这样的一个窘境,这种情况下小程序提供了另外两项能力,一个是数据预拉取,一个是周期性更新,对于第一项能力,在这个小程序启动的时候,由微信提前异步调用开发者设置的云函数或者是数据接口,拿到这个数据以后再传递给小程序使用,第二项能力是微信每隔12小时轮询开发者设置的云函数或者是数据接口,将这个数据在微信本地缓存起来,然后由开发者在小程序里边直接取用,这两项能力都非常不错,它们可以进一步降低小程序冷启动里面的时间消耗,下面我们看项目实践。 首先看实践一,后台开启数据预拉取与周期性更新。 首先我们需要登录小程序的后台,在后台里面有一个开发 开发管理 开发设置这个页面,往下拉我们就可以看到数据周期性更新及数据预拉取的设置区域了,单击开启便可以开启相应的能力,在这个地方我们可以填写服务器端的接口,或者是选择我们的云环境下面的一个云函数,如果是选择使用这个服务器接口,在本地测试的时候还需要使用内网穿透工具,例如frp,frp是一个开源工具,可以在本地免费使用,将外网网络请求映射到本地,如果是使用云函数就简单很多,需要备案的域名也不需要了,这个服务器也不需要了,内网穿透工具更加不需要了,我们在这个示例里面选择的是第二种方式 使用云函数。 下面我们进行实践一的代码演示。 在后台开启数据预拉取与周期性更新,这个操作需要我们登录小程序的后台打开mp.wexin.qq.com,然后用我们的微信管理员账号扫码就可以登录了,登录以后在我们左边导航栏里面选择开发,然后是开发管理,接着选择开发设置,开发设置这个页面我们往下拉,这个地方有数据周期性更新和数据预拉取,这两个区域的一个设置如果你没有开启的话,这个地方有开启按钮,单击开启用管理员账号扫码就可以开启了,开启以后需要填写一些信息,如果是选择云环境的话需要填写云环境ID,同时填写一个我们自己编写的云函数,这个云函数你自己在测试的时候目前还没有,稍后我们会在小程序里面进行创建,包括前面云环境ID,云环境ID如果你没有开启的话可以在开发者工具里面然后手动进行开启,开启以后就可以拿到这样的一个环境ID了,后面这个还可以修改,然后这两个我们在测试的时候 为了简单方便,我们写的是同样的一个云函数名字 都是getHomeData同样的一个的地址,代码演示我们就说到这里。 下面我们看实践二,创建云函数getHomeData。 开始改造这个小程序前端代码,需要先实现这个云函数getHomeData,它的主要代码其实就是为了实现从后台提供了一个数据这样的一个功能,这个代码跟我们原来的Go语言后台里面实现的代码很类似,只不过我们是拿JS然后再重新写一遍,它的这个目的就是返回我们首页的一个数据,云函数在编写的时候可以使用本地测试功能进行调试代码,代码完成以后我们一定不要忘记部署这个服务器,云函数它虽然是在本地编写的,但是它却是运行在微信的服务器上,当开发者在小程序里面调用云函数的时候相当于调用这个服务器端的一个接口,只不过中间的调用这个协议它是微信私有的,开发者不能查看和干涉。 下面我们看实践二的代码演示。 首先第一步我们要做一个事情,我们目前这个项目其实它没有包含云开发的目录,即使你已经在这个项目上开启了云环境,如果我们不设置的话它仍然是没有的,需要改一下配置文件开启云开发目录的一个支持,看一下我们最终源码,找到这个项目的配置文件,在这个地方 这有一行代码cloudfunctionRoot等于cloudfunctions,这个是设置我们的云开发函数目录,将这个配置拷贝到我们当前的项目配置文件里面,放在这里,改完以后,我们小程序项目将它重启一下。 重启是为了让它读取我们的修改之后的项目文件,我们这个目录现在还没有出现,因为我们配置里边添加以后,但是我们本地这个目录还没有,所以我们还需要手动创建这样的cloudfunctions这样的一个目录,创建完成以后我们可以看到它这个地方有一个默认环境的绑定,如果它没有绑定 我们在这个地方还可以手动选择,设置完以后在这个上面可以选择同步云函数列表,这个同步它是从我们这个服务器上将我们之前已经编写的云函数同步到我们这个项目本地的目录下面来,这个里面有getHomeData,现在我们可以看到点开以后它里面还没有东西,因为我们只是同步一个列表,现在我们选择下载,下载的时间稍微有点慢,这个地方完成以后它会有个提示 完成的一个提示,到现在是下载完成了。 下载完成以后,单击打开getHomeData这个目录可以看到下面它是有一些文件的,其中index.js这是我们的云函数的一个主文件,这个地方我们看一下,首先最上面我们是对SDK的一个引入,下面是一个环境的初始化,这个地方是我们一个数据,就是我们上面有一个banner图的地址,这个地址当然现在还是本地地址,然后再往下就是main函数了,它是导出的 给外面使用的这个里面的一个代码,我们可以看一下 跟我们后端Go语言里面写的代码结构很类似 ,只不过它是拿JS语言重新写了一下,然后会返回一个数据。 我们在编写云函数的时候可以选择两种方式进行测试一个是本地测试 一个是云端测试,我们打开云开发面板,打开以后选择云函数,在这个里面找到我们的getHomeData云函数对吧,然后这个地方有一个本地调试 我们选择本地调试,什么是本地调试,就是我们云函数代码它的本地模拟运行,原本它是在服务器上运行,但是为了我们调试方便可以在本地运行,这个地方我们可以选择以后会打开一个Tab标签,选择以后这个地方开启本地调试,请求方式我们可以选择手动触发就可以,因为它本身不需要什么参数,所以这个请求参数可以不设置。 在完成以后单击调用,单击调用以后,接下来可以看到这个地方调用完成,然后这个地方会有一个结果的打印出来,这就是我们取到的首页的一个数据信息,这个是本地调试,本地调试如果没有问题以后要将我们的云函数上传 部署在我们这个云函数列表里面,然后你右击 它这个地方有一个上传并部署,云端安装依赖 就是这个选完以后,它就可以部署到云端了,这个云函数一定要部署到云端,然后我们才可以在小程序后台进行相关的一个设置,部署到云端以后在云开发面板里面它还有一个云端测试,同样还是选择云函数,然后选择 这是我们的getHomeData云函数,然后后面有一个云端测试 选择这个就可以了,这种方式它是方便我们测试上传到云端以后它的运行状态是不是正常,做最后的一个测试,一般情况下我们本地测试没有问题,上传到云端以后也不会有什么问题,这个代码演示我们就说到这里。 下面我们看实践三,使用并发复合命令的竞赛模式拉取数据。 云函数准备好以后就可以改写retrieve_home_data.js这个文件了,这个里面有我们拉取首页数据的代码,原来我们通过wx.request接口,从后端接口拉取数据的代码仍然保留,另外我们需要添加两个新的对新接口的一个调用,以这种新的方式进行首页数据的一个拉取,第一个接口是wx.onBackgroundFetchData这样的一个接口。这个接口是设置微信在拿到预拉取数据的时候,然后我给它设置一个回调函数,如果设置回调函数的时候微信它已经拿到了这个数据,那么这个回调函数它就不会触发了,第二个接口是wx.getBackgroundFetchData,这个接口是我们主动去获取微信在本地缓存的预拉取数据,但如果本地它没有缓存数据,这个接口它也会获取失败,这两个接口都不是100%可靠的,它们并不能保证我们一定可以拿到我们想要的数据,所以在使用的时候,我们必须将它们与我们原来的wx.request那种调用方式结合起来使用。 并发复合对象ParallelCommand它有一种竞赛模式默认没有开启,我们将类对象的第二个参数,也就是raceMode设置为true则可以开启,开启以后各个子命令 无论是哪一个先完成,则视为复合命令对象完成,一个代码修改完以后,我们最后修改一下这个项目的配置,在这个项目的详情面板里面有一个叫做启用数据预拉取这样的一个选项,这个选项开启以后微信开发者工具它会在小程序运行的时候,向开发者配置的预拉取的接口或者是云函数发出数据的一个请求,如果没有意外的话,在调试区测试的时候就可以看到我们设置的打印信息了,三种方式 同时拉取首页数据,在模拟器里面测试的时候可能wx.getBackgroundFetchData这种方式最先拿到数据,当它拿到数据以后,其他渠道的数据我们就不需要再考虑了。 下面我们进行实践三的代码演示。 我们先看一下我们的最终的一个代码,这个代码改造主要位于我们的library services下面的 retrieve_home_data在这个里边,在这个里面我们需要加两个新的拉取数据的方式,这是一个,这个是一个 这个是我们设置回调onBackgroundFetchData,微信拿到这个数据的时候我们监听,监听以后通过监听回调函数拿到这个数据。另外这个地方又是一个,这个地方我们是通过getBackgroundFetchData,这个地方是我们主动地去拉,同时fetchType等于pre就代表的是预拉取,这是一种方式 ,然后后面这种方式,这是从后端接口拉取数据,这是我们原来就有的拉取方式,这种方式我们需要保留。然后在这个地方实例化ParallelCommand的时候,我们是在requestCmd前面加了两种方式,同时它的第二个参数raceMode,我们给它设置为了true 改为了竞赛模式,这就是最终代码,我们将最终代码给它拷贝一下,这是我们需要的一个代码,这些都是。 然后到我们目前的项目里面找到这个文件,在这个地方我们先把这个代码粘过来,然后注意看requestCmd,这跟我们下面这个是重合的,所以这一块代码其实不需要 这个是不需要的,这个注释我们可以把它拿到下面来 拿到这个地方,然后前面我们有两个,这三条的模块引入代码是一样的,保留一个就可以了,这个地方,这个是设置我们预拉取的时候设置一个token,这个toke其实可以帮助我们标识,在服务器端标识我们当前用户的一个身份,当然我们这个地方没有传递身份,我们这个地方直接传了一个确定的这样的一个字符串。实际上我们可以根据当前用户的不同,把id还有appid等等相关的一个身份标识信息可以通过这地方然后传过去,如果是需要的话可以传这个信息,这个是我们的第一个拉取方式,我们将这个拉取方式放在我们的这个地方,这里这是一个,另外还有第二个预拉取,放在这里,然后再看一下我们最终代码里面的一个设置,只有这三个 后面就没有了,只有这三个,然后有一个true的参数,在这个地方,所以这个地方它其实我们是新建了一个拉取,这个地方代替的是我们原来这个,我们把这个代码给它拷贝一下放在这里,这是我们新建的一个复合命令对象,它在下面这个位置,就这个,我们要代替这些 代替它,后面这个是保留的,然后这个是raceMode等于true这样的一种方式,我们这个代码已经搞完了。 接下来我们进行测试,单击编译,在我们这个项目的详情面板里面、本地设置里面,它会有一个叫做启用数据预拉取,我们选择这个,这个地方有一个错误,它说这个文件加载不到,static images下面找不到一个BANNER的文件,我们可以确认一下我们这个目录下面有没有这样的一个文件,看一眼没有,我们找一个给它复制过来,找一个有的给它复制过来,最终源码里面应该是有的,最终源码里面因为它都实现网络化了,本地目录没了,所以它里面没有,我们从另外一个地方找。已经放进来了,继续我们新功能的测试,看这个打印 数据准备好了,然后渠道 getBackgroundFetchData,这个就是我们主动的数据预拉取 取到的数据,这个打印说明我们新的代码其实已经生效了,代码演示就到这里。 下面我们看实践四,周期性数据更新。 周期性数据更新与数据预拉取的使用很像,首先我们也需要在后台开启周期性数据更新的能力,并且把这个云函数相关信息填写好,然后我们就可以在retrieve_home_data.js文件里面添加新的数据拉取渠道了,执行时间就要放在后端接口拉取数据的前面,新渠道的拉取代码与数据预拉取,只有fetchType的参数不一样,其他代码都是一样的,使用这个数据预拉取的时候它参数值是pre,获取周期性更新的数据的时候它这个参数值是periodic,获取周期性更新的数据并不能保证我们一定可以获取成功,这个数据微信是每隔12小时轮询一次,如果是我们刚在后台开启这个能力马上在微信小程序这个工具里面进行测试的话,这个时候会得到一个data not found这样的一个运行时错误,这个错误是正常的,它不会对我们这个程序造成负面影响,因为我这边里面不止一个渠道,一个渠道坏了 还有其他渠道可以顶上,在微信开发者工具测试周期性数据更新的时候,我们还可以选择菜单 工具里面的拉取周期性缓存数据这样一个选项。开启以后我们再次测试就看不到上面提到的运行时错误信息了,但是我们要注意拉取它是拉取一次 测试一次,你下次想测试的时候还需要再单击一下这个菜单。 下面我们进行实践四的代码演示。 首先我们看一下我们最终的源码,对于我们retrieve_home_data文件的一个改造主要是有哪些改动,在预拉取的下面有一个新的获取周期性更新的数据,这个对象实例是fetchData3Cmd,在这个里面它主要与我们前面的主要的一个差别就在于我们fetchType的不同,前面预拉取是pre,然后这个地方变成了periodic,periodic其实就是周期性的一个意思,这个方式是周期性更新,我们将这个代码给它拷贝一下。 这个代码我们要在哪里使用,新的对象实例是在这个地方,放在requestCmd的前面进行使用,回到我们自己的项目里边来找到这个文件,然后放在这个地方,本身它对象实例放的一个位置已经显示了它在复合对象里边的一个次序,这个实例放在它的前面 它的上方,所以我们在这个列表里面也要放在它的前面,放在这个位置,这样就可以了,其他的我们也不需要修改了,代码搞定了。 接下来我们在微信开发者工具里面测试一下,当然测试的时候我们可以选择菜单里面的一个选项 ,这个地方我们可以看一下,它有一个运行时的Error,data not found一个提示,我们不用管这个错误,现在我们选的工具里面有一个拉取周期性缓存数据,然后单击一下,单击以后然后我们再单击编译进行测试,看到了吧,刚才的data not found提示已经不存在了,在我们单击这个选项的时候,开发者工具帮我们拉取了一下数据,周期性数据它们帮我们缓存了,它已经可以取到了 所以它错误信息就不再出现了,这个代码演示我们就说到这里。 最后我们总结一下,对于周期性更新和数据预拉取这两项能力 我们要明白,它们是为优化弱网络环境下的网络请求而存在的,如果可以肯定网络没有问题或者小程序启动的时候,没有要紧的网络数据请求,这种情况下就可以不使用它们,还有很重要的一点一定要明确,无论使用哪种方式都有失败的可能,这种增强的能力它可以作为我们快速拉取数据的辅助手段,但是一定不应该作为唯一的手段,直接的云函数调用以及后端数据接口的一个调用还是要保留的。这节课我们就讲到这里,上面显示的这些网址是本课所涉及的一些文档地址。 点击查看开放文档: 数据预拉取周期性更新数据缓存 /周期性更新 /wx.getBackgroundFetchData小程序调试 /数据预拉取调试 这节课我们主要学习了如何使用数据预拉取和周期性更新以及如何创建云函数,还有如何使用并发复合命令的一个竞赛模式,下节课我们学习如何优化小程序端发出的网络请求。 最后我们说一下思考题,这里有个问题请你思考一下,Quic被称为第三代互联网通讯协议,通讯效率比旧版本好了很多,当我们使用Go语言作为后端编程语言的时候,我们有什么样的一个办法可以快速开启对Quic协议的一个支持,我们知道小程序端现在已经完全支持这种协议了,如果服务器端也支持的话将能大大提高我们前后端接口的一个通讯效率,这个问题先留给你思考一下,下节课我们对这个问题进行一下深入的探讨。