专栏首页QAPM-腾讯客户端性能分析QAPM小程序性能监控难点与解决方案
原创

QAPM小程序性能监控难点与解决方案

春节快乐,干货来袭。QAPM小程序质量套件服务于包括银行等公司内外多个产品,本文对小程序的SDK做技术揭秘。

目前公司内外存在多个小程序的监控方案,包括微信提供的原生方案、Aegis、Fundebug和听云等,那么对比这些的监控方案,QAPM的小程序质量套件有什么不同呢?

(1)定位不同:相比专注于做一个优秀的工具,QAPM的小程序质量套件定位于数字体验监控(DEM)。利用关联分析、可视化和机器学习等方法,实现性能、用户行为的监控、观察和分析,核心聚焦于用户体验。

(2)问题域不同:手中有锤子,眼前都是钉子。传统的小程序监控工具,都是在描述问题上做研究,目的是如何把问题描述得更清晰;QAPM的小程序质量套件,在复现和解决问题上具有天然的优势,内置用户行为点击事件的监控能力,可以清晰的得知用户操作路径,通过回放用户操作,解决研发不易复现问题的痛点,提高修bug的速度。

(3)技术不同:使用全新hook技术,完美实现对只读的wx下的方法的hook操作;对Page参数进行解析,获取用户点击的相对坐标和绝对坐标,完美拿到用户的点击操作。

(4)稳定性优势:QAPM的小程序质量套件可靠性高,具备银行标准,目前服务于广州农村商业银行和长沙银行。

一、QAPM小程序SDK做了什么事情?

小程序SDK采用无埋点方案,通过hook一些关键的小程序api,例如wx.request、App.onError等,在不影响业务的正常运行的情况下,获取到这些api的入参、执行时间等信息,并在合适的时机做数据组装和上报,达到获取性能数据的目的。

二、hook小程序的关键api

1.监控的关键api有哪些?

请求监控:wx.request

页面性能监控:Page.onReady、Page.onLoad、Page.onShow、Page.onHide、Page.onUnload

启动监控:App.onLaunch

jserror监控:App.onError

2.如何hook?

(1)直接替换法

Page和App下的方法可读可写,所以直接替换就可以完成hook了。以App.onLoad为例,先把原来的onLoad复制一份,接着用新的函数替换掉原来的onLoad,并在新函数中执行自定义的代码:

Page和App下的其它方法都是用这种直接替换的形式完成hook。要完成正常的记录时间的功能,就需要在执行原来的方法前后,分别执行一次获取时间戳的函数。要完成记录错误堆栈的功能,就得截获wx.onError的参数,并做好堆栈信息的处理和上报。

(2)使用Object.defineProperty

wx这个对象下的方法是只读的,使用上述的“直接替换法”走不通,因此需要使用其它办法,经过一系列探索,最终决定采用Object.defineProperty这个方法。MDN上对这个方法的描述是这样的:

Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

下面是如何使用Object.defineProperty对wx.request进行hook操作的源码。这里的关键其实就是Object.defineProperty(wx,"request",{……}),其中value里面定义了hook之后执行的我们的代码,主要包括4个步骤:

(1)在请求开始的时候,记录请求的方法和url

(2)开启正常的请求

(3)为请求结束的回调函数config.complete注入我们的代码,主要是记录请求的方法、url、请求状态码res.statusCode、请求内容config和响应内容res

(4)如果hook失败了,则把wx.reqeust替换成原来的wx.request,以免影响正常的业务逻辑

源码如下:

于是我们就完成了对微信小程序关键的api的hook操作,并对页面的各个生命周期的开始和结束时间戳做了记录,对小程序发请求的接口做了请求耗时、请求和响应内容的记录。

三、获取setData的性能数据

setData在整个小程序的数据更新中起到重要作用,获取setData的性能数据对优化渲染耗时有一定的帮助。setData的性能数据包括使用次数、执行时间和更新数据的大小。有2个方法可以获取这些东西:

1.基础库在2.12.0以下的版本,需要采用上述的“直接替换法”进行hook操作,在调用setData的时候和它的回调函数中分别执行一次获取时间戳的操作,从而得到耗时的性能数据。

2..基础库在2.12.0以上的版本,微信提供了一个接口可以直接获取setData的性能数据,这个接口是setUpdatePerformanceListener,提供3个时间戳:

(1)此次更新进入等待队列的时间戳

(2)更新运算开始的时间戳

(3)更新运算结束的时间戳

sdk以(1)和(3)的差值作为setData的耗时,包括了等待队列的时间和实际做更新运算的时间。

具体的接口参数信息可以参考微信小程序的这篇官方文档:setUpdatePerformanceListener文档

调用这个封装好函数的时机是在hook Page的时候,需要把page作为参数传入,才能够获得当前的page的setData信息,代码逻辑主要有这几块:

(1)对原始的setData做好备份

(2)对基础库2.12.0以下的版本,使用方法1进行hook,并分别在setData开始的时候、和在回调中做好时间戳的获取和存储

(3)对基础库大于2.12.0的版本,使用方法2,用setUpdatePerformanceListener获取setData的精确耗时数据

(4)出错了就执行备份的setData,保证不影响正常的业务逻辑

这两个方法的合并后的源码如下:

 四、用户行为

小程序中,使用一些技巧可以获取到用户点击页面的x和y轴的坐标点,

原理:sdk在对Page的所有方法进行hook的时候,解析page的参数,其中page的第一个参数中,有一个叫做touches的字段,里面包含有pageX、pageY、clientX和clientY这些字段,含义就是相对于整个页面的绝对坐标点和在当前窗口中的坐标点。

由此我们就可以获取到点击的坐标信息了,坐标点信息配合点击的页面名称和时间戳等基础信息,就可以做用户行为的回放功能。

截取一段对page的hook的源码如下:

 五、jserror堆栈信息的行列号和文件名的翻译

1.这块其实比较简单,分3个步骤实现翻译功能:

(1)获取错误堆栈信息,方法是hook wx.onError

(2)获得当前版本的sourcemap文件,在微信开发者工具点击上传小程序,就可以得到这个文件了,如果是线上版本,则可以直接去微信小程序管理平台下载

(3)使用现有的sourcemap转换工具库实现翻译功能

下面以nodejs的source-map库举个例子:

 2.选取map文件的技巧:

(1)当sourcemap文件夹下面存在APP文件下时,则直接选取这个文件夹下的map文件来翻译

(2)否则选取FULL文件夹下的map文件来翻译

(3)正常来讲,需要先选对map文件,接着运行以上代码之后,就可以将看不懂的行列号和文件名翻译成看得懂的行列号和文件名了

3.框架开发的小程序如何翻译jserror的堆栈?

当使用框架来开发小程序时,如果要正确翻译,则需要遵循以下步骤:

(1)注意将webpack打包的devtool属性设置成source-map,这样打包后的文件就会给每个js文件都对应生成一个map文件

(2)走正常的上传小程序的流程,获取sourcemap文件。

微信小程序有一点做得比较好的就是这里了:我们生成了那么多的map文件,是不占用小程序宝贵的2MB的大小的,正常上传上去,就会带上刚才给每个js文件生成的map文件,小程序这边会将这一系列的map文件做好合并处理。经过这一系列的操作之后,就能够完美的将大部分的jserror的堆栈信息翻译成可读性较高的信息了。

QAPM小程序的sdk中,比较重要的一些技术细节就是上面说到的5大类了。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • QAPM — 一款强大且细腻的APP性能专项解决方案

    QAPM是我们腾讯云专项测试技术中心其中一个较为成熟的产品,是针对移动App的一个一站式性能解决方案。

    QAPM腾讯客户端性能分析
  • 【私有化质量实践2】最“年轻”的云原生数据服务

    随着云架构的不断普及,“未来的软件一定生长于云上”的理念被越来越多的人所接受。云提供了一种面向企业应用实现按需进行资源分配的模型,以一种全新的、高效的方式来部署...

    010101011001
  • “定位”那些事儿—sigkill定位爆内存问题

    导语:定位爆内存crash原因—iOS App性能中影响各位开发友人发量的重要问题,我们通过对QAPM上报的一例sigkill有效个例的分析,为大家提供一些思路...

    QAPM腾讯客户端性能分析
  • 【私有化质量实践1】出了问题要“坐牢”的SDK

    后台都还好,SDK跟着这些金融类产品发布。我们总开玩笑说,一旦出问题,都是“坐牢”的事情,瑟瑟发抖呀。当然,也许“坐牢”不必,但是前一阵某金融行业内部的产品,就...

    010101011001
  • 从0到1,QAPM在私有化实践过程中的质量保障

    QAPM(移动监控)在TMF中交付已经走过两个年头,两年的时间,我们也在不断成长。截止到2020年12月,QAPM私有化工单数量收敛,安灯工单数48单下降到8单...

    010101011001
  • 微视iOS SIGKILL BUG实例

    微视iOS接入QAPM作为项目的性能监控工具已有一年多,打开的功能包括掉帧率、卡顿、SIGKILL、内存触顶、VC泄露和大块内存监控。在QAPM同学的日常运营过...

    QAPM腾讯客户端性能分析
  • 亮相深圳2019MTSC大会,腾讯WeTest携手行业专家搭建“质量专场”

    ? 背景   12月14日,2019年度中国移动互联网测试开发大会(Mobile Testing Summit China,简称 MTSC)深圳站于深圳科兴...

    WeTest质量开放平台团队
  • 技术揭秘,QAPM的这位Android内存分析“专家”

    QAPM原有Android内存快照分析是基于那个颇具历史感的MAT的命令行版本开发的。MAT到现在都依旧是最最强大的内存快照分析工具,就是他那个类SQL的查询能...

    010101011001
  • 告别重复告警打扰--基于堆栈相似度的全新QAPM告警方案

    导语 为了能够及时的发现问题并及时解决,QAPM提供了一套卡顿告警机制。正如同常规的阈值触发的告警机制一样,QAPM早期的告警也会使测试开发人员陷入告警风暴的影...

    QAPM腾讯客户端性能分析
  • 腾讯测试中台实践与交流活动圆满结束

    ? 2019年5月5日,腾讯WeTest作为测试敏捷化标准协会成员之一,主办的测试中台交流和参观活动,在腾讯上海分公司总部园圆满举行。来自浦发卡中心、太平洋保...

    WeTest质量开放平台团队
  • 腾讯测试中台实践与交流活动圆满结束

    原文链接:https://wetest.qq.com/lab/view/457.html

    WeTest质量开放平台团队
  • 【私有化质量实践3】“千奇百怪”的Web

    经过我们的“千锤百炼”,总结出来在私有化交付中Web的难点无非有两方面:一是用户环境复杂,导致了许许多多的兼容性问题;其次,可能是完全没有共性的用户需求,可以这...

    010101011001
  • 能“理解代码”的缺陷分配服务之技术内核

    如果缺陷没有分配给正确的人,会导致重要缺陷不断流转,很慢才能解决;而在流转的过程中会增加大量的交接成本——我们观察到一个简单的缺陷在流转中会浪费超过5天(见下图...

    010101011001
  • 透视QAPM Android新卡顿&新启动分析的技术方案

    类似的反馈我们收到了太多了,卡顿方案的缺陷也一直是我们的痛点。一个事件下存在大量的执行函数,而方案是基于阈值满足的前提下才执行的堆栈抓取,这样会产生堆栈偏移,有...

    010101011001
  • 测试开发者盛宴!WeTest邀您一同参加2019 MTSC移动测试开发大会

    ? 导读   MTSC2019 中国移动互联网测试开发大会(Mobile Testing Summit China)由国内最大的测试开发技术社区之一 Tes...

    WeTest质量开放平台团队
  • 大数据平台是否更应该容器化?

    作者颜卫,腾讯高级后台开发工程师,专注于Kubernetes大规模集群管理和资源调度,有过万级集群的管理运维经验。目前负责腾讯云TKE大规模Kubernetes...

    Spark学习技巧
  • QAPM新内存分析"专家",帮你分析内存问题根因

    QAPM原有Hprof分析是基于开源项目LeakCanary的shark Andoroid Extension,这里仅有针对安卓内存泄露部分,同时包含了一个极其...

    QAPM腾讯客户端性能分析
  • 【解决方案】民爆器材仓库视频监控要解决哪些难题?EasyNVR远程视频监控突发险情的必要性

    爆炸品仓库监控室需对仓库各堆放区、装卸运输区进行安全监控,仓库各库区对环境条件有严格限制,需要对温度、湿度、通风程度等有严格的限制,防止存储的爆炸品因为受潮而引...

    EasyNVR
  • MTSC 2019 深圳站议题总览

    Are you ready?来 12 月的深圳穿短袖。2019 年 12 月 14 日 MTSC 深圳站,TesterHome 全体主创人员期待穿羽绒服的,穿冲...

    云加社区

扫码关注云+社区

领取腾讯云代金券