测小程序的性能,而不是宿主的
小程序是:你的代码,跑在一个不是你写的 App 里,跑在一个你控制不了的运行时上,跑在一台不是你挑的硬件上。这句话的每一部分都是一个测量问题。
你实际量到的是什么
把性能采集的范围设成宿主 App,你拿到的是:宿主自己的界面、它的网络请求、它的埋点、它后台在做的一切,加上你的小程序。你的代码在这个总数里的某个地方,而且没法分辨占了多少。
也就是说这个数字不能当基线、不能跨会话对比,别人说你的小程序重的时候也拿不出手。
解法是把范围收到小程序自己的进程上。多数宿主会为每个小程序单开一个进程 —— 它们就是这样把彼此隔离、也和宿主隔离的。附到那个进程上之后,CPU、内存和帧率描述的才是你的代码。
有些开销仍然不是你的
即使范围收对了,也有一部分开销是结构性的:
- 运行时启动。 你的第一行代码跑起来之前,宿主得先把小程序容器拉起来。这段时间算在会话里,而你优化不了。
- 桥接开销。 你的 JavaScript 每一次调用原生能力都要跨一次边界。它不免费,而且在你自己的代码里看不见。
- 宿主的渲染管线。 你描述一个视图,宿主决定怎么画。你的帧率取决于一个你分析不了的渲染器。
- 共享的内存上限。 宿主和里面所有小程序共享这个 App 的内存配额。被杀掉完全可能是别人的锅。
分清这几件事,是这里大部分的功夫所在。一个把容器启动算进去的冷启动数字,不是对你代码的公平衡量;把它当真,就会花一周去优化一个你改不了的东西。
值得测的几项
冷启动、热启动,以及两者的差。 跑一次,杀掉,再跑一次。差值大致是缓存起作用的那部分,底线大致是结构性的那部分。
一次往返里的内存。 进入你的小程序、使用、退出、再进来。如果底线每次都在抬高,你就是在一个和别人代码共用的进程里泄漏 —— 最后会被算到别人头上,最后大家一起被杀。
列表上的帧率。 小程序最常见的单一投诉就是滑动性能,而原因几乎总是节点太多,或者图片尺寸不对。
网络流量,而不是请求数。 你可能看不到请求本身,但看得到字节数。一个打开就拉五兆的小程序,从外面就能看出有问题。
关于硬件
小程序的用户群明显偏向老设备 —— 很多时候这正是它存在的理由:一个比装 App 更轻的选择。所以你桌上那台旗舰在这里比平时更不具代表性。
用你能找到的最便宜的设备测。一个在当代手机上没问题、在四年前机型上没法用的小程序,恰恰在它被设计出来要解决的那件事上失败了。
数据在哪
宿主 App 的沙盒里放着你的小程序的存储。读它能一次性解决一整类原本只能靠猜的问题:缓存到底有没有写进去、包有没有更新、本地数据库是不是预期的大小、下载的资源完不完整。
平常那条注意事项在这里要加倍:那是宿主的沙盒,里面除了你的数据还有别的小程序的数据。只看你自己的,取能回答问题的部分,用完就删。
怎么把结论摆出来
当你需要向宿主平台团队解释你的小程序的开销时 —— 迟早会有这一天 —— 拿得出手的材料是:
- 进程级的采集,不是宿主级的
- 指明设备型号的冷启动和热启动数据,并附上设备状态
- 改动前后同一项测量的两次结果
宿主后台面板上的一个数字,只是对话的起点。一次在明确设备上、按进程采集的结果,才是答案。
