背景
此前有开发者反馈小程序发布新版本后,新版本覆盖率比较慢,因为小程序的更新机制是异步的,部分用户不会马上应用上新版本。
小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。 假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台态的小程序切换到前台,这个过程就是热启动;冷启动指的是用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动。
小程序的异步更新发生在冷启动过程,当发现新版本后,会异步下载新版本的代码包,但不会马上应用上最新版本,需要等小程序下一次冷启动,才会应用上新版本。
解决思路
为了解决这个问题,我们内部也经历了数个方案的讨论,这里简单介绍下:
1. 同步检查更新(放弃):可能是最直接的解决思路,但主要问题是会影响小程序的启动速度,当下小程序的更新迭代是非常频繁的,部分用户可能每次启动都命中更新,如果需要同步检查更新+同步下载新的版本,那将会影响这部分用户的启动体验。
2. 模块热替换(放弃):从技术上来说,这是最好的方案,小程序运行起来后,在打开新页面时,马上应用新版本里的页面,但这就会存在新旧逻辑、页面共存问题,对于开发者来说,反而更不好处理,特别是涉及到全局变量时,情况会更复杂,对于我们已有的框架来说,也是一个大挑战,不过这个也是我们之后努力的方向。
3. 定时 check 新版本(目前方案):6.6.3 及以上版本的客户端,会定时 check 最近使用过的小程序是否有发布新版本;如果有,下次打开的时候会同步更新新版本再打开。这可以保证在新版本发布 24 小时后,所有小程序都能使用最新版本。(这部分是微信客户端自身优化,开发者无需关心)
4. 异步更新 + 强制更新(目前方案):同步检查更新与模块热替换两者之间的折衷方案,即还是维持异步更新机制,在异步下载完小程序代码包后,提供重启小程序的能力,这样在遇到紧急问题时可以马上解决。
异步更新 + 强制更新方案介绍
从基础库 1.9.90 开始,我们提供了 wx.getUpdateManager 接口,使用该接口,可以获知是否有新版本小程序、新版本是否下载好以及应用新版本的能力。
当小程序冷启动时,会自动向微信后台请求新版本信息,如果有新版本,会马上触发新版本的下载。开发者可以通过 wx.getUpdateManager,获知当前更新的状态。
wx.getUpdateManager 接口会返回一个 UpdateManager 实例,UpdateManager 包含了三个回调:
1. onCheckForUpdate:当小程序向后台请求完新版本信息,会通知这个版本告知检查结果
2. onUpdateReady:当新版本下载完成,会回调这个事件
3. onUpdateFailed: 当新版本下载失败,会回调这个事件
还有重启应用新版本的接口:
1. applyUpdate:当新版本下载完成(onUpdateReady),调用该方法会强制当前小程序应用上新版本并重启
具体示例:
// wx.getUpdateManager 在 1.9.90 才可用,请注意兼容
const updateManager = wx.getUpdateManager()
updateManager.onCheckForUpdate(function
(res) {
// 请求完新版本信息的回调
console.log(res.hasUpdate)
})
updateManager.onUpdateReady(function
() {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否马上重启小程序?',
success: function
(res) {
if
(res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
updateManager.onUpdateFailed(function
() {
// 新的版本下载失败
})
更详细信息可以参考 UpdateManager 的详细文档
最佳实践
从用户体验上来说,我们还是建议只在非常必要时才强制用户重启更新,例如出现线上紧急 BUG。通常情况下,可以选通过 wx.showModal 弹出选择框让用户选择是否重启更新(实现请参考示例代码)。
如何调试
最新版本的微信开发者工具提供了强制更新的调试能力,通过编译模式 - 编辑编译模式 - 勾上「下次编译时模拟更新」即可在开发者工具上调试强制更新功能。
最新开发者工具下载链接 点我。
那最迟24小时的机制,是否能跳过?确保所有用户能更新只能等待24小时吗?
能否强制更新?
定时 check 新版本的方案,如果有,下次打开的时候会同步更新新版本再打开,这有可能是热启动吗?
定时 check 新版本(目前方案) 目前大概是多久check一次?
那么 热启动的情况该怎么处理呢 如果有bug时热启动该如何更新
有文章说 wx.getUpdateManager ,上传代码时要选择 “版本更新” 代码才会生效有效,是这样得嘛?
这个调试更新的流程,只是开发本地可以,但是如果QA测试同学,用体验版验证版本升级功能,怎么办呢?
企业微信环境打开小程序,不手动关闭企业微信的话 不会提示版本升级? 是什么问题?,请问有什么解决方案?
wx.showModal({ title: '更新提示', content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~', showCancel:false }) 如果接口检测到用户使用的小程序版本跟服务器版本对应的不一致,提示该文字,对于年轻人来说可能很容易理解,但是一些不怎么用软件,手机的用户,他们可能更希望有,小程序端点确定的时候直接进入微信小程序列表中更容易些,小程序是否有该功能???
该功能能否在体验版上进行测试体验呀?只能线上吗?很不方便。。
因为:::
我目前是app.js
onLaunch
加检查更新代码 wx.getUpdateManager()
但,
小程序 :1.0.0,服务器1.0.0
如果小程序1.0.0接口请求服务器 1.0.1接口,会返回要小程序强制更新的状态码。
这个时候,即便小程序后台也已经发布了1.0.1对应服务器1.0.1。
可用户正在使用的过程中,接口返回强制更新状态码。
但部分用户使用小程序并不能立刻检测到,那让该用户重启小程序是否就可以了呢?实践发现有时候重启似乎还是不行的。。。
是建议:加如下代码提示吗?
updateManager.onUpdateFailed(function () { // 新的版本下载失败 wx.showModal({ title: '更新提示', content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~', showCancel:false }) });
体验版可以测试更新弹窗吗