升级微信版本8.0.32后 部分华为手机 TensorFlow模型加载失败 解决方案(切换wasm后端 仅供参考)
发现问题:部分客户反馈之前正常的进入的游戏,现在进入后白屏无法继续 定位问题过程: 1、尝试本地复现问题 用开发工具模拟、真机(IOS)调试都无法复现 2、因为代码近期没有版本,暂时先排除代码问题,怀疑是微信版本升级或者是鸿蒙系统 3、统计后发现出现问题的用户都是华为手机,且小程序近期升级了版本(初步锁定) 4、社区开始有反馈问题的帖子 找来测试机还有同事的手机验证 结果发现华为 P30 pro、mate 30 不行,mate 40 pro 可以 5、随后社区技术运营专员给出了原因和解决方案 【https://developers.weixin.qq.com/community/develop/doc/0002a81b9709e846fb1fb9b235c000?highLine=tensflow%2520%25E5%258D%258E%25E4%25B8%25BA%25E6%2589%258B%25E6%259C%25BA%2520%25E5%258A%25A0%25E8%25BD%25BD%25E5%25A4%25B1%25E8%25B4%25A5】 [图片] 总结:[图片] 确定方案:在"菊厂"不支持的前提下,只能采用小程序官方推荐的方案 -- 针对异常机型切换到wasm后端 执行方案的过程:因为个人能力有限([图片]) 和社区的部分同胞一样,陷入泥潭,举步维艰...... 痛苦了两天后放弃了,因为这个项目是定制活动项目,在主营业务迎来高峰期后,用社区的反馈截图安抚了客户之后,就开始了繁忙的业务迭代... [图片] 没多久活动就结束了,天真的以为不用再处理了,结果证明是我 too young,too simple 几个月后,客户开展了第二期活动,产品跟客户沟通后,需要解决让我排期调研,尽量解决!!!【内心崩溃 抓狂】 因为当时业务还在紧张的迭代中,给了1天调研时间,在一阵搜索之后找到了一篇博客(链接如下),初看有种皇天不负有心人的冲动,仔细一看心里一咯噔,要改源码,博客给的方案基于uni-app,我们用的是wepy + 原生,略微差异,问题不大(预感不祥) 博客链接:https://blog.csdn.net/CSDN_LQR/article/details/130046132 (下文截图来源) 经过一通折腾,引入wasm后还对原先的小程序分了包,但是在最后一步卡住了,需要修改@tensorflow/tfjs-backend-wasm库的源码(加载wasm文件,调研时用setWasmPaths方法设置在线链接好像是可以的),当时直接替换编译后的代码,应该哪里还有问题,只能给客户回复不好弄,还需要时间尝试 后面继续业务迭代,又搁置了... [图片] [图片] 分包问题(有坑,后续详细说明) [图片] 业务高峰期后,迭代里的需求少了后,这个问题又被拉出来,排进迭代,排了两天时间和一位同事(打call)一起解决,第一天因为个人原因卡在匪夷所思的问题上,仅仅梳理了下之前的思路,第二天因为上午有迭代需求,下午才开始研究,尝试了博客的方法 1、在设置wasm路径这里卡住了,上次调研用的在线链接不支持了,查看官方文档发现WXWebAssembly 目前只支持加载包内 wasm 文件 [图片] 2、尝试博客里的解决方法setWasmPaths使用本地路径,wasm文件放在static目录下,代码如下,但是编译之后,通过/static/tfjs-backend-wasm.wasm 无法找到文件 [图片] 3、此路不通,但是之前使用在线链接的时候,代码是可以进入到setBackend步骤的,这里就进入查看分析源码阶段了 之前的博客提到 tfjs-backend-wasm 这个库中的代码还是使用的 WebAssembly,而微信小程序把 WebAssembly 废弃,改为 WXWebAssembly,所以需要通过rollup插件将编译代码中的 WebAssembly 相关部分,修改为 WXWebAssembly 但是突然发现源码中的WebAssembly 都已经改成 WXWebAssembly了,上Github果然看到了merge记录 [图片] [图片]应该是个已经被修复了,不过时间这块我有点懵,我记得第一次看源码的时候确实和博客里面一样,都是WebAssembly,但是这次确实都改成了WXWebAssembly,不过既然已经修复,那就不用考虑插件替换源码的问题了,只需要完成wasm路径设置即可成功切换wasm后端 因为之前使用在线链接的时候,代码是可以进入到setBackend步骤的,所以考虑还是用setWasmPath设置在线路径,这里把之前的CDN链接换乘本地链接,发现可以通过,不过还是有报错,但是至少不是卡在路径设置这里了,根据报错继续分析问题 报错信息:WXWebAssembly.instantiate 第一个参数必须是string 参考链接:https://developers.weixin.qq.com/miniprogram/dev/framework/performance/wasm.html [图片] 查看源码对比发现,WXWebAssembly.instantiate第一参数接收的是binary,问题定位 源码中支持的是通过远程链接加载到本地,通过二进制文件初始化WXWebAssembly,但是WXWebAssembly目前只支持包内路径加载(信息不同步啊) [图片] 解决方案:使用setWasmPath方法(要废弃)设置本地路径,改造下createInstantiateWasmFunc方法 编译运行 画面正常 -- 真棒👍(哈哈哈)不过升级过后确实很卡,没辙 [图片] ⚠️注意:我这里是直接引用的修改后的@tensorflow/tfjs-backend-wasm源码导出的setWasmPath方法(还有其他方法的欢迎评论区留言谈论) [图片] [图片] [图片] 源码位置: [图片] 因为方案用的setWasmPath方法后续可能会被废弃,只能暂时解下燃眉之急,不明白setWasmPaths为什么设置本地路径失败,知道的小伙伴欢迎评论区留言@我,万分感谢 结语:社区是一个互相帮助的地方,希望大家在这里都能收获问题的解决方案或者思路,以上都是个人的见解,有更好的方案或者建议欢迎大家评论留言