可通过performanceobserver监听longtask类型精准捕获主线程阻塞超50ms的任务,结合performance.now()打点分析异步任务排队与执行耗时,区分宏/微任务延迟,并利用attribution定位源头,实现卡顿归因与优化。

可以通过 Performance API 结合事件循环的运行机制,间接测量异步任务(如 setTimeout、Promise.then、fetch 回调等)在事件循环中排队和执行的实际耗时,关键在于利用 performance.now() 记录时间戳,并结合任务调度时机做差值分析。
用 performance.now() 精确标记异步任务生命周期
performance.now() 提供亚毫秒级精度的时间戳,不受系统时间调整影响,是监控异步耗时的首选。不能依赖 Date.now(),它精度低且可能回拨。
- 在任务入队时(如
setTimeout(fn, 0)调用瞬间)记录起始时间 - 在回调执行第一行代码处立即记录结束时间
- 两者差值即为“从入队到开始执行”的总延迟(含宏任务排队、微任务清空、JS 主线程空闲等待等)
区分宏任务与微任务的监控策略
事件循环中,宏任务(setTimeout、setInterval、I/O 回调)和微任务(Promise.then、MutationObserver)的调度优先级不同,需分别建模:
- 监控宏任务延迟:在
setTimeout(..., 0)调用前打点,回调内立刻再打点 → 得到「调度延迟」 - 监控微任务响应:在
Promise.resolve().then(...)的then调用前打点,回调内打点 → 反映「微任务队列积压程度」 - 注意:连续多个
Promise.then会链式加入微任务队列,首尾时间差可反映当前微任务负载
捕获真实执行耗时(排除排队时间)
仅知道“何时开始执行”还不够,还需分离“执行本身花了多久”。可在回调内部用嵌套 performance.now() 测量纯业务逻辑:
- 示例:
const start = performance.now(); doHeavyWork(); const end = performance.now(); console.log('执行耗时:', end - start); - 配合宏/微任务入口时间戳,就能拆解出「排队时间 = 入口时间差 − 执行耗时」
- 这对定位是卡在调度(如主线程长期忙碌)还是卡在计算本身,非常关键
用 PerformanceObserver 监控长任务(Long Tasks)
Chrome 及主流浏览器支持 PerformanceObserver 监听 longtask 类型,直接上报阻塞主线程 ≥ 50ms 的任务块(含 JS 执行、渲染、布局等):
- 启用方式:
new PerformanceObserver(cb).observe({entryTypes: ['longtask']}) - 每个
longtaskentry 包含startTime、duration和attribution(来源如scriptEvaluation),可关联到具体脚本或异步回调 - 虽不直接标出“异步”,但大量异步回调集中执行常触发 longtask,是性能瓶颈的重要线索
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











