对于中小型技术团队来说,为了打造一个移动端线上应用来实现一款APP的开发与维护成本是难以接受的,但传统的H5又会遇到各种性能问题与安全性问题,这时大家可能就会选择开发一款小程序进行平替,由于小程序均以超级APP(如微信、支付宝)作为载体,开发者可以根据开发者文档快速地开发小程序,并且能够方便、安全地使用超级APP提供的各种基础能力(如:支付、扫码、定位等),小程序应用本身天然拥有快速的加载能力、原生应用的体验等特性
回到主题,小程序作为前端应用也必然需要对项目进行生产环境运行时监控,本文就来聊聊关于小程序监控
本文阅读成本与收益如下:
阅读耗时:6mins
全文字数:5k+
预期效益
- 搭建微信小程序基础监控体系
监控什么
在开始搭建小程序项目监控逻辑之前我们先来回忆一下,在web开发的时候我们一般会监控上报哪一部分的数据
- 系统相关
- onerror
- Promise
- 路由切换
- 网络请求
- 用户体验相关
- performance
- 用户行为
- 页面启动耗时
而在小程序当中所需要进行监控上报的内容基本上保持一致,追求实现应用高性能表现的同学可能还需要新增小程序中特有的setData
方法的耗时监控
本文描述基于微信小程序框架,其它应用小程序思路通用
怎么监控
js-error监控
首先我们先来处理最常见的前端JS错误监控
在web中有window.onerror
的全局错误回调方法,在小程序中同样有一个功能类似的方法wx.onError
const onErrorCallback = function(msg = '') {
console.error('wx:onError:', msg)
try {
if (['APP-SERVICE-SDK', 'webviewSDKScriptError', 'webviewScriptError'].some(key => msg.indexOf(key) > -1)) {
// 基础库报错
// 上报
report('baseError', msg)
} else {
// 上报
report('jsError', msg)
}
} catch (e) {
console.error(e)
}
};
wx.onError && wx.onError(onAppError)
复制代码
通过以上方法我们便可以在小程序应用全局范围内捕获到js-error
的错误信息
Promise、async监控
以上全局监控还有一类js相关的错误尚未捕获到,那就是Promise
回调函数内引起的错误,正常情况下应该需要开发者通过向then
的第二个参数传入错误处理回调函数或者链式调用catch
来捕获错误并进行相关的处理
小程序框架为了帮助开发者解决这类问题,贴心的准备了另一个apionUnhandledRejection
,专门用于监听未处理的 Promise 拒绝事件
const onUnhandledRejectionCallback = function(event = {}) {
console.error('wx:onUnhandledRejection:', event)
const { reason } = event
// 上报
report('unhandledRejection', reason)
}
wx.onError && wx.onUnhandledRejection(onUnhandledRejectionCallback)
// wx.onAppHide && wx.onAppHide(onAppHide)
复制代码
performance性能监控
作为一名优秀的前端研发者,处理完js-error监控后我们开始关注应用在生产环境的实际性能表现情况
同样的,在微信小程序当中开发者可以使用一个特殊的性能数据计算APIwx.getPerformance
wx.getPerformance
:获取当前小程序性能相关的信息
const performance: any = wx.getPerformance();
const observer = performance.createObserver((entryList) => {
console.log('>>>load resource data', entryList.getEntries());
});
observer.observe({ type: 'resource' });
复制代码
例子:SVG资源请求性能数据
通过传入不同的type可以实现各类性能数据的采集
若想同时采集不同type的数据,可以使用options.entryTypes
页面路由
讲到小程序页面路由,我们一般会联想到wx.navigateTo
、wx.navigateBack
等几个API,而现在我们需要设置一个监控,当用户进入到一个新的页面就进行数据上报,所要上报的数据包含基本用户信息、页面path
第一个思路:在所有的页面onLoad中通过this.route拿到页面path并进行上报
优势:
- 操作简单
- 无hack行为
问题:
- 后续每一个页面当中都会含有相同的上报代码逻辑
- 需要保证后续新增的页面都要添加一段上报模版代码
可见其操作实践起来非常繁琐
第二个思路:拦截所有的页面路由切换/跳转方法,像wx.navigateTo
、wx.navigateBack
等
优势:
- 监控上报逻辑代码复用
- 不用担心页面新增问题
问题:
- 无法拦截
navigator
标签组件 - 对
wx
全局对象的属性进行hack
第三个思路:自定义Page函数MyPage
,在MyPage
中定义监控上报逻辑,到最后将处理完成的页面对象数据重新交回给原生Page
函数处理(推荐做法)
优势:
- 可以进行页面监控上报
- 不hack全局变量
- 可根据业务需要注入工具函数
- 代码复用率高
问题:
- 每个页面的JS文件均需要引入
MyPage
而非直接使用Page(可通过脚手架代码生成解决问题)
// utils.js
export default function MyPage(pageOptions: any = {}) {
console.log(this.route); // pages/index/index
report('enter path', this.route); // 上报页面path
const defaultOptions = {
// 默认属性配置
};
pageOptions = Object.assign({}, pageOptions, defaultOptions);
Page(pageOptions);
}
// index.js
import { MyPage } from '@/common/utils.js'
MyPage({
behaviors: [],
data: {
msg: 'demo'
},
methods: {}
});
复制代码
网络请求
请求类型的监控,用过axios等请求库滴同学都应该有了解或使用过请求拦截器
在小程序里面我们也能够通过对微信官方提供的请求APIwx.request
进行封装,实现拦截器的自定义功能
const handleRequestComplete = function (res) {
report('request log', res); // 上报请求监控数据
}
const baseUrl = 'https://xxx.xxx.com'
export const commonRequest = function (method = 'GET', options) {
if (!options.url) {
return false;
}
const isFullUrl = options.url.indexOf('http') > -1;
const base = isFullUrl ? '' : baseUrl
return Promise((resolve, reject) => {
wx.request({
method,
url: base + options.url,
header: options.header,
data: options.data,
success: function (sucessRes) {
resolve(sucessRes);
},
fail: function (failRes) {
reject(failRes);
},
complete: handleRequestComplete // 处理请求完成后的回调函数
})
});
}
复制代码
以上便是小程序当中最简单的请求封装实现,通过自定义wx.request
的complete
回调函数逻辑实现请求的监控
写到最后
剩下的还有用户行为以及页面启动耗时的监控,这里就留给大家思考一下应该如何进行监控逻辑的设计,有了以上例子的介绍相信大家对于小程序监控有了一定的了解,即使是微信之外的小程序框架体系下进行开发,监控的思路也是一致的,只需要理清楚平台框架提供的基础能力就能够轻松实现
谢谢大家,我们下节再见!!!
感谢各位看到这里,如果你觉得本节内容还不错的话,欢迎各位的点赞、收藏、评论,大家的支持是我做内容的最大动力