Performance.mark() 和 Performance.measure() 是浏览器原生高精度性能标记工具:mark() 打时间锚点,measure() 计算两点间耗时,需配合 getEntriesByType() 提取上报,并注意命名规范、存在性校验及兼容性。

Performance.mark() 与 Performance.measure() 是浏览器 Performance API 中轻量、高精度、零依赖的原生性能标记工具,非常适合在关键业务节点(如按钮点击、接口响应、渲染完成)插入自定义埋点,无需引入 SDK 即可采集毫秒级时序数据。
用 mark() 打下关键业务“时间锚点”
mark() 用于在代码执行流中打下命名的时间戳,相当于给业务流程标出“起点”或“里程碑”。它不触发上报,只记录当前时刻(相对于 navigationStart 的毫秒数),且支持重复命名(后续同名 mark 会覆盖前一个)。
- 在用户点击“提交订单”按钮时立即调用:
performance.mark('order_submit_start') - 在 React 组件
useEffect中确认首屏内容已挂载后标记:performance.mark('homepage_rendered') - 避免在异步回调深处随意打点(如未 await 的 fetch.then 内),否则可能因执行时机漂移导致时序失真
用 measure() 关联两点,计算真实业务耗时
measure() 通过指定起始 mark 名和结束 mark 名,自动计算二者间的时间差,并将结果存入 performance entries。它本质是“逻辑段耗时”的封装,比手动 Date.now() 差值更可靠(不受系统时钟调整影响,精度达微秒级)。
- 测量从点击到接口返回的全流程:
performance.measure('order_submit_duration', 'order_submit_start', 'order_api_resolved') - 若只传一个参数(如
performance.measure('render_time', 'homepage_rendered')),则默认以 navigationStart 为起点 - measure 后可通过
performance.getEntriesByName('order_submit_duration', 'measure')获取结果对象,含 duration、startTime、name 等字段
结合 getEntriesByType() 提取并上报数据
所有 mark 和 measure 都会作为 PerformanceMark 或 PerformanceMeasure 实例存在内存中,需主动提取。建议在业务关键路径收尾处(如接口成功回调、路由跳转后)批量采集并轻量上报。
- 只取 measure 类型条目(即你关心的耗时段):
const measures = performance.getEntriesByType('measure') - 过滤出业务相关名称(如 /^order_.*_duration$/),避免混入框架内部 mark
- 上报时建议附带上下文:当前页面 URL、用户 ID(脱敏)、设备类型、是否首屏等,便于多维归因
- 注意内存:长期运行单页应用应定期清理(
performance.clearMarks()/performance.clearMeasures()),但不要在上报前清空
注意事项与避坑提示
这两个 API 表面简单,实际使用中容易忽略细节导致数据不可用或偏差。
- mark 名称必须是合法字符串(不能含空格、控制字符),建议统一小写下划线命名,如
'pay_button_click' - measure 的 start/stop mark 必须已存在,否则生成的 entry duration 为 0 —— 可加简单校验:
if (!performance.getEntriesByName('xxx', 'mark').length) console.warn('missing mark: xxx') - 不支持跨 iframe 或跨 tab 共享 mark,每个上下文独立维护;Service Worker 中不可用
- 部分低端安卓 WebView 对 Performance API 支持不全,上线前需做兼容检测:
if ('mark' in performance)

















