背景
作为商户Saas私域会员系统的转化两个入口分别是小程序扫码支付环节和店员新增会员,两种方式,近期,业务侧反馈会员系统中转化而来的会员和商户消费客流差距较大,由于扫码付界面会以会员优惠诱导用户免费开通会员,所以大概率会员与客流差距不大,所以大概率确定可能由于某些链路环节出现了问题,导致会员转化率大打折扣。
目前公司小程序是没有监控系统的,基本上全靠开发人员的自测和测试人员的回归测试等,所以亟待解决的就是保证系统的健壮性,及可用性,自然而然需要引入全链路监控系统,拿数据说话了。
监控系统
为什么选
目前我们的需求是引入一个成熟的全链路监控系统,并且不做私有化部署,因为原先的一些系统用的sentry,但是基本上没有人去关注监控数据,并且随着版本发展也不做监控系统更新,并且一系列的报警部署等都是问题,引用现成的才是最适合目前的需求的。
并且我们还需要一个包含多个平台的监控系统,通俗来说就是方便后期也能进行其他PC系统、原生系统的监控接入,最好是低侵入的,所以最后我们选定了火山引擎提供的全链路监控平台,目前支持App端、Web端、PC端、小程序端、OS端多个端的监控,并且收费不贵。
接入
监控平台的SDK接入非常简单,直接跟着说明书做即可:
指标
目前没看到埋点的功能及错误回放的功能,总的来说够用,只要接入了SDK,它初始化会自动生成UUID的user_id来进行唯一标识用户,所以最重要的就是在渲染前初始化SDK,如下就是天级的打分:
现在来看看对于小程序有哪些指标:
-
启动性能
- 首屏冷启动总耗时:pageRenderEnd-App.trigger
- 小程序初始化耗时:appInitEnd-App.trigger
- 下载耗时:performance.downloadPackage
- JS注入耗时:performance.evaluateScript
-
页面性能
- 初次渲染耗时FR:performance.FR.duration
- 页面首次绘制耗时FP:FP.startTime-loadStart
- 页面首次内容绘制耗时FCP:FCP.startTime-loadStart
- 页面最大内容绘制耗时LCP:LCP.startTime-loadStart
-
运行性能
- setData耗时:setData总耗时/pageview数量(代表一次PV平均累计的setData耗时)
定位问题
接入系统后,我们首先来关注PV/UV,可以明显排查到首页PV/UV过高,那么首页可能用户经常刷新,大概率应该是白屏过长或者用户网络不稳定导致的小程序下载缓慢等原因,这都可以从监控的性能指标中了解到,定位到问题,就可以做解决了。
优化
一般项目的优化手段可以分为两方面,针对传统性能指标的优化及针对以用户为中心的指标的优化:
针对传统性能指标的优化
优化思路
- 网络优化:这种优化都是全局生效、一劳永逸的、投资回报率也很高(ROI)
- 缓存优化:除了常见的HTTP缓存,还有Memory缓存、Cache API缓存、Push缓存等
- 资源加载优化:从请求时机、文件体积、加载方式等方向优化
网络优化
- 开启HTTP2:关注兼容性问题,同时做好域名收敛
- 开启brotli压缩:相比gzip,它具有更高的压缩比和更快的压缩性能
- 善用HTTPS:通过有效的优化手段,如Session Resume、OCSP Stapling等,提升HTTPS性能
- 使用CDN部署静态资源:有效降低访问延迟,提高可用性
- DNS预解析:常用于CDN域名场景,减少DNS耗时
<link ref='dns-prefetch' href='//cdn.demo.com'>
- 提前建立网络连接:常用于Server API等域名,兼容性更好,
<link ref='preconnect' href='//demo.com'>
缓存优化
从上到下进行:
资源加载优化
一般从请求时机、文件体积、加载方式等方向入手
优化HTML文件
- 控制体积在30kb以内
- 优化DOM节点
- 压缩
- 谨慎使用内联
优化JS文件
- 请求时机:defer/async/动态加载
- 文件体积:常规的压缩/Tree Shaking/按需加载/精准控制polyfill
- 加载方式:减少网络请求/充分利用缓存
优化CSS文件、字体文件、图片文件
- 请求时机:关键的先请求,次要的后请求
- 文件体积:如何才能让资源的体积更小?
- 加载方式:减少请求数/善用缓存
优化以用户为中心的关键指标
优化FP&FCP
尽快渲染,加载快、解析快、渲染快,最终的值才会越优秀
- 消除阻塞渲染的资源
- 缩小CSS&&移除未使用的CSS
- 预连接到所需的来源
- 减少服务器响应时间
- 避免多个页面重定向
- 预加载关键请求
- 避免巨大的网络负载
- 使用高效的缓存策略服务静态资产
- 避免DOM过大
- 最小化关键请求深度
- 确保文本在页面字体加载期间保持可见
- 保持较低的请求数和较小的传输大小
优化FMP&LCP
缩短页面关键路径的渲染时间
主要受四个因素的影响
-
缓慢的服务器响应速度:策略:网络优化
-
JS和CSS渲染阻塞:策略:削减CSS、延迟加载非关键CSS、内联关键CSS、削减压缩JS文件、延迟加载未使用的JS文件、最大限度减少未使用的polyfill
-
资源加载时间:策略:优化和压缩图片、预加载重要资源、压缩文本文件、自适应服务(不同设备显示不同图片)
-
客户端渲染:最小化关键JS、使用服务端渲染、预渲染
优化FID
如何快速地响应用户交互
-
分割长任务:拆分成尽可能小的异步任务
-
优化页面,尽快做出交互准备
- 移除关键路径上非必要组件加载的脚本
- 尽量大限度地减少需要在客户端进行后处理的数据量
- 按需加载第三方代码
- 优先加载可以为用户提供最大价值的内容
-
使用Web Worker
-
减少JS执行时间
优化CLS
尽量减少布局偏移
CLS较差的常见原因
-
无尺寸的图像:设置宽高、或者通过CSS宽比容器预留所需的空间
-
无尺寸的广告、嵌入和iframe:预留空间、避免在可视区域顶部放置广告、使用占位符或预先计算足够的空间
-
动态注入的内容:预留空间,比如使用占位符或骨架屏等
-
导致不可见文本闪烁/无样式文本闪烁的网络字体:预加载字体
-
在更新DOM之前等待网络响应的操作:倾向于使用transform动画,而不是触发偏移
优化TTI
尽快的渲染、尽早的请求、请求尽快结束、尽量避免长任务
- 参考如何优化FCP
- 预加载关键请求
- 最小化关键请求深度
- 减少JS执行时间
- 最小化主线程工作
- 保持较低的请求数和传输大小
总结
基本上可以从上面考虑,进行针对性优化,这里就不阐述了
用户可用性保障
为了保障用户可用性,最主要的是进行JS错误的监控和请求监控
JS错误监控
异常报警:阈值类的报警意义不大,重点关注波动报警和新增报警,可以设置版本release,这样新版本的报警就可以查看到,波动报警可重点关注错误率和影响用户率
请求监控
异常监控:5分钟或10分钟,关注波动,这往往意味着线上故障,推荐选择请求路径作为归因维度
请求耗时监控:设置天级别的任务执行间隔,请求耗时75分位值作为度量指标,选择设置波动大小,可以选择设置阈值大小
支付转化率提升
对于小程序,分两个阶段,一个扫码到进入小程序阶段,这属于黑盒阶段,我们可以进行通用指标优化,即体积、压缩、分包等优化,一个是小程序操作过程优化,可以进行以用户为中心的优化,比如缩短白屏时长,加快首屏渲染,减少JS错误率,减少请求错误率,可用以下指标衡量