小程序发布之后,用户开始使用,这时候开发者最担心什么?担心某个页面打不开了,担心某个按钮点了没反应,担心在某些机型上直接闪退。更让人焦虑的是,用户不会主动告诉你出了什么问题,他们只会默默地关掉小程序,再也不回来。

性能监控和错误上报,就是解决这个问题的工具。它让开发者在用户遇到问题的时候能够第一时间知道,甚至在用户自己都没意识到的时候,就已经收集到了线索。

监控什么:三个核心维度

线上监控不是越多越好,抓大放小才是正道。对于小程序来说,最值得关注的是三个维度。

第一个维度是错误。包括脚本报错、接口报错、页面渲染失败。这些会直接影响用户能不能正常使用。第二个维度是性能。包括页面打开速度、切换速度、滑动流畅度。慢不一定不能用,但会劝退用户。第三个维度是行为。用户走到哪一步就流失了,哪个按钮点击率异常低。这类数据帮助定位体验问题。

错误和性能用代码监控,行为用埋点分析,三者结合起来才有价值。

错误监控:捕捉每一个异常

小程序提供了原生的错误监听接口。在app.js中声明onError方法,可以捕获大部分运行时的脚本错误。

javascript
// app.js
App({
  onError(error) {
    console.error('捕获到错误:', error)
    // 上报到自己的监控服务
    this.reportError({
      type: 'script',
      message: error.message,
      stack: error.stack,
      timestamp: Date.now()
    })
  }
})

onError能捕获的是脚本执行错误。对于接口请求错误,需要自己在封装的请求函数中统一处理。

javascript
function request(options) {
  return new Promise((resolve, reject) => {
    wx.request({
      ...options,
      success: (res) => {
        if (res.statusCode >= 400) {
          reportError({ type: 'api', status: res.statusCode, url: options.url })
        }
        resolve(res)
      },
      fail: (err) => {
        reportError({ type: 'network', url: options.url, errMsg: err.errMsg })
        reject(err)
      }
    })
  })
}

还有一个容易被忽略的错误来源:Promise中未捕获的reject。小程序不会自动上报这类错误,需要开发者手动添加全局的unhandledrejection监听,但这个API在小程序环境支持度不一,稳妥的做法是在每个Promise链末尾都加上catch。

性能监控:测量关键节点

启动耗时是最重要的性能指标。从用户点击小程序图标,到首页内容渲染完成,这个时间决定了用户的第一印象。

小程序的性能面板和wx.getPerformance API可以获取到详细的启动阶段数据。

javascript
// 在首页的onReady中记录
const performance = wx.getPerformance()
const observer = performance.createObserver((entryList) => {
  entryList.getEntries().forEach(entry => {
    if (entry.entryType === 'navigation') {
      // 上报启动耗时
      reportPerformance({
        type: 'launch',
        duration: entry.duration,
        path: entry.name
      })
    }
  })
})
observer.observe({ entryTypes: ['navigation', 'render'] })

页面切换耗时同样重要。用户在列表中点击一项进入详情页,这个跳转过程如果超过300毫秒,就会有明显的等待感。在A页面的跳转代码处记录开始时间,在B页面的onReady中计算差值。

javascript
// 列表页
const startTime = Date.now()
wx.navigateTo({
  url: '/pages/detail/detail?id=123',
  events: {
    pageReady: () => {
      const duration = Date.now() - startTime
      reportPerformance({ type: 'navigate', duration, from: 'list', to: 'detail' })
    }
  }
})

// 详情页
onReady() {
  const eventChannel = this.getOpenerEventChannel()
  if (eventChannel) {
    eventChannel.emit('pageReady')
  }
}

界面流畅度可以用帧率来衡量。scroll-view组件提供了bindscroll事件,可以记录滚动时间戳,但计算精确帧率比较麻烦。一个简化的做法是监控滚动事件触发的频率,正常情况下每帧都会触发一次,如果频率明显下降,说明存在掉帧。

行为监控:追踪用户路径

错误和性能数据告诉开发者在哪出问题,行为数据帮助理解用户做了什么才触发这些问题。

在关键的页面和按钮上做埋点:

javascript
// 封装一个埋点函数
function track(eventName, properties = {}) {
  const data = {
    event: eventName,
    properties: properties,
    page: getCurrentPages().pop()?.route,
    timestamp: Date.now(),
    sessionId: getSessionId()  // 会话标识
  }
  // 发送到分析平台
  sendToAnalytics(data)
}

// 使用示例
onLoad() {
  track('page_view', { from: this.options.from })
}

onTapBuy() {
  track('click_buy', { productId: this.data.product.id, price: this.data.product.price })
}

行为数据的一大价值是计算转化漏斗。比如商品详情页到下单页的转化率突然下降,可能是下单按钮出了问题。结合错误监控数据,就能快速定位。

数据上报的策略与坑

实时上报会带来额外的网络请求,密集的埋点甚至可能影响小程序本身的性能。常用的优化策略是批量上报。

在内存中维护一个队列,累积到一定数量(比如10条)或者间隔一定时间(比如5秒),再将队列中的数据打包一次性发送。

javascript
class Reporter {
  constructor() {
    this.queue = []
    this.timer = null
  }
  
  add(data) {
    this.queue.push(data)
    if (this.queue.length >= 10) {
      this.flush()
    } else if (!this.timer) {
      this.timer = setTimeout(() => this.flush(), 5000)
    }
  }
  
  flush() {
    if (this.queue.length === 0) return
    const data = this.queue.slice()
    this.queue = []
    if (this.timer) clearTimeout(this.timer)
    this.timer = null
    
    wx.request({
      url: 'https://monitor.example.com/report',
      method: 'POST',
      data: { events: data }
    })
  }
}

上报请求本身也可能失败。这时候应该放弃这批数据,而不是无限重试。因为上报失败意味着当前网络环境可能很差,继续重试只会增加负担。丢数据总比影响主功能好。

注意上报的数据量。每条上报信息附带用户标识、设备信息、页面路径等基础字段是必要的,但不要在单个事件中携带整个data对象的副本。把无关的冗余数据去掉。

第三方监控工具

自己搭建一整套监控系统工作量大,大部分小程序团队会选择现成的工具。

微信小程序后台自带数据分析功能,包括访问分析、实时日志、错误日志。优点是零接入成本,缺点是功能有限、数据不开放、不支持自定义维度的聚合查询。

腾讯云和阿里云都有小程序监控产品,提供错误聚类、性能分析、用户行为追踪等功能。接入方式通常是在项目中引入一个SDK,配置好AppKey即可。

开源方案有Sentry,它提供了小程序SDK,支持sourcemap解析,错误堆栈可读性高。适合已经有自建Sentry服务的团队。

从监控到行动的闭环

数据收集只是第一步。只有建立起从监控到修复的闭环,监控才有意义。

设置合理的告警阈值。启动耗时超过3秒的占比超过5%,触发告警。报错率超过1%,触发告警。告警要发给对的人,不要半夜吵醒所有人。

每周复盘监控数据,找出最频繁的三个错误,安排修复。下个月再看这三个错误的出现频率是否下降。

监控不是上线后才做的事。从开发阶段就应该接入测试环境的上报,让测试人员跑出来的问题也能被记录和分析。

电话咨询
QQ咨询
在线咨询
服务投诉