很多朋友开发支付宝小程序时,都会遇到线上“看不见的问题”:用户反馈点按钮没反应、页面突然白屏,自己在测试环境又复现不了,这时候就需要一套监控体系,把线上的异常和性能问题抓出来,及时修复减少用户流失。本文就讲怎么用生活化的逻辑,搭建适合不同基础开发者的支付宝小程序错误与性能监控体系。

一、明确要监控的对象:未捕获异常与性能指标

1.1 啥是要抓的未捕获异常?

就是代码里没被“接住”的错误,比如变量名写错没定义就用、调用接口没判断返回结果、异步操作出错没写处理逻辑,小程序运行到这些地方就会直接崩掉,页面白屏,用户不知道原因就退出去了。

1.2 要监控哪些性能指标?

核心是三个:页面从打开到能正常用的加载时间、接口请求的耗时(慢接口会让用户等得不耐烦)、脚本有没有卡顿(比如某个函数跑太久,导致页面点不动)。

二、核心方案:捕捉未捕获异常的具体做法

2.1 用支付宝小程序官方API监听全局错误

支付宝小程序有两个自带的全局API,专门用来抓未捕获的异常和未处理的异步错误,我们只要在小程序的入口文件(app.js)里加上这两个监听,就能把错误上报到自己的后端,不用复杂的第三方库。 技术栈:支付宝小程序 JavaScript

// app.js 支付宝小程序入口,负责全局监听错误和性能
App({
  // 记录小程序启动时间,用来算页面加载耗时
  launchTime: Date.now(),
  // 全局错误监听:捕捉所有没被try-catch接住的代码错误
  onError(error) {
    // 组装错误的关键信息,方便后续排查
    const errorData = {
      type: 'global_code_error', // 错误类型
      message: error.message, // 错误的具体描述,比如“变量未定义”
      stack: error.stack, // 错误的调用栈,能找到是哪一行代码出问题
      currentPage: getCurrentPages().pop()?.route, // 当前用户在哪个页面
      appVersion: this.globalData.version, // 小程序版本号,方便看是不是老版本的问题
      device: my.getSystemInfoSync().model // 用户的手机型号,排查是不是机型兼容问题
    };
    // 上报错误到后端,放到请求回调里处理,不阻塞用户操作
    my.request({
      url: 'https://你的后端地址/api/monitor/error',
      method: 'POST',
      data: errorData,
      success: () => console.log('错误上报成功')
    });
  },
  // 监听未处理的异步错误:比如异步请求失败没写catch
  onUnhandledRejection(rejectInfo) {
    const errorData = {
      type: 'unhandled_async_error',
      reason: rejectInfo.reason, // 异步操作失败的原因
      currentPage: getCurrentPages().pop()?.route,
      appVersion: this.globalData.version
    };
    my.request({
      url: 'https://你的后端地址/api/monitor/error',
      method: 'POST',
      data: errorData
    });
  },
  // 全局存储的公共数据,比如版本号可以在这里统一管理
  globalData: {
    version: '1.0.0' // 后续可以从my.getAccountInfoSync动态获取,不用手动改
  }
});

2.2 补充:页面与组件内的局部异常监听

有时候全局监听可能漏了页面组件里的小错误,这时候可以在每个页面的JS里加简单的try-catch包裹可能出错的函数,举个例子:

// 某页面的goods.js,比如商品详情页的处理函数
function addToCart(itemId) {
  try {
    // 这里的逻辑可能出错,比如itemId传错,或者接口异常
    my.request({
      url: 'https://你的后端地址/api/cart/add',
      data: {itemId},
      success: (res) => {
        // 正常逻辑
      }
    });
  } catch (err) {
    // 手动上报局部错误,全局监听没抓到的小问题
    my.request({
      url: 'https://你的后端地址/api/monitor/local_error',
      method: 'POST',
      data: {
        page: 'goods',
        error: err.message,
        itemId: itemId
      }
    });
  }
}
module.exports = { addToCart };

三、性能指标监控的实现方法

3.1 页面加载性能监控

我们可以利用小程序的路由生命周期,计算页面从打开到能正常显示的时间,超过200毫秒就上报,用户不会等太久才看到内容的话体验更好。

3.2 接口请求性能监控

很多小程序的卡顿都来自慢接口,我们可以封装自己的请求函数,代替原生的my.request,自动记录接口的耗时,超过500毫秒就上报:

// 封装的请求函数,用来监控接口性能,支付宝小程序 JavaScript
function monitorRequest(options) {
  const startTime = Date.now(); // 记录请求开始时间
  // 合并默认配置,和原生request保持一致
  const finalOptions = { method: 'GET', timeout: 10000, ...options };
  // 调用原生请求
  my.request({
    ...finalOptions,
    success(res) {
      // 计算耗时
      const duration = Date.now() - startTime;
      // 如果耗时超过500ms,上报性能数据
      if (duration > 500) {
        my.request({
          url: 'https://你的后端地址/api/monitor/performance',
          method: 'POST',
          data: {
            type: 'api_slow',
            url: finalOptions.url,
            duration: duration,
            status: res.status, // 接口返回的状态码,比如200、500
            page: getCurrentPages().pop()?.route
          }
        });
      }
      // 执行用户传入的回调,不影响原来的逻辑
      finalOptions.success?.(res);
    },
    fail(err) {
      // 接口请求失败的话,也上报
      const duration = Date.now() - startTime;
      my.request({
        url: 'https://你的后端地址/api/monitor/performance',
        method: 'POST',
        data: {
          type: 'api_fail',
          url: finalOptions.url,
          duration: duration,
          errorMsg: err.errMsg
        }
      });
      finalOptions.fail?.(err);
    }
  });
}

3.3 脚本卡顿监控

如果某个函数执行太久,会导致页面点不动,这时候可以用定时器定期记录时间差,超过50毫秒就认为有卡顿,上报:

// 脚本卡顿监控示例,支付宝小程序 JavaScript
let lastCheckTime = Date.now();
// 每隔100ms检查一次时间差,判断有没有卡顿
setInterval(() => {
  const now = Date.now();
  const gap = now - lastCheckTime;
  // 如果时间差超过50ms,说明有卡顿
  if (gap > 50) {
    my.request({
      url: 'https://你的后端地址/api/monitor/performance',
      method: 'POST',
      data: {
        type: 'script_stuck',
        stuckTime: gap, // 卡顿的毫秒数
        currentPage: getCurrentPages().pop()?.route,
        // 尝试获取当前执行的函数,这个可以用监控工具的扩展,新手可以先忽略
        currentFunction: '未知函数'
      }
    });
  }
  lastCheckTime = now;
}, 100);

四、这套方案的实际应用场景

比如做奶茶店的支付宝小程序,用户选好奶茶点击下单,突然页面白屏,这时候监控会抓到这个未捕获的错误,我们马上能发现是下单接口调用时变量名写错,导致接口请求失败。再比如商品列表加载慢,耗时1200毫秒,性能监控会上报这个接口,我们发现是商品列表接口没加缓存,加上本地缓存后,加载时间降到200毫秒,用户不再抱怨加载慢。还有小游戏类小程序,脚本卡顿会导致操作延迟,监控会抓到卡顿,优化后游戏体验提升,用户留存提高。

五、方案的优缺点复盘

5.1 优点

用支付宝官方API,不用引入复杂的第三方库,小团队也能快速搭建;错误和性能数据都是实时上报,比用户反馈的更真实;可以自定义上报的维度,比如页面、机型、版本,排查问题更精准;适合不同基础的开发者,只要把示例代码粘进去,改个后端地址就能用。

5.2 缺点

自己搭建需要后端存数据、做可视化,对于只有前端的小团队来说,要兼顾后端会增加一点工作量;有些极端场景(比如小程序被系统杀死)可能监不到错误;性能监控的阈值需要自己调,调太严会误报,太松没用。

六、落地时要注意的细节

6.1 别让监控影响小程序性能

上报请求要放到后台异步执行,不要阻塞主线程,比如用request的success回调处理,或者延迟上报,不然用户操作会卡顿。

6.2 遵守隐私相关规定

不要上报用户的敏感信息,比如手机号、支付密码,只能传匿名的设备ID或者用户ID后几位,符合个人信息保护的要求。

6.3 避免重复上报

同一个错误10分钟内只上报一次,不然会打崩自己的后端,比如用一个缓存存已上报的错误key,相同的就不再发请求。

6.4 先测试再上线

故意写一个未捕获的错误,看会不会上报;故意让某个接口变慢,看性能数据会不会上报,确保监控体系正常工作,不要上线后才发现监控没生效。

七、总结

搭建这套支付宝小程序监控体系,核心就是用官方提供的监听API,把线上的异常和性能数据上报到后端,不用复杂的技术,只要跟着示例代码一步步改,就能快速落地。这套方案能帮我们及时发现线上问题,优化用户体验,减少用户流失,不管是新手还是有经验的开发者都能用上,是小程序上线后必不可少的辅助工具。