chrome performance面板中红色或深黄色长条即长任务,点击后通过call tree按self time排序可定位耗时函数源头,并支持跳转源码;还可用performanceobserver监听longtask、console.time标记及排除layout/paint等伪长任务。

直接看 Chrome Performance 面板的 Main 轨道,红色或深黄色长条就是长任务,点开它就能定位到具体函数。
在 Performance 面板中展开调用栈
录制操作后,找到 Main 轨道里超过 50ms 的长条(默认已高亮),鼠标悬停会显示“Long Task”;点击它,在下方 Summary 或 Bottom-Up 标签页中:
- 切换到 Call Tree,按 “Self Time” 降序排列,排在最上面的叶子函数就是真正耗时的源头(比如某个 getter 触发了强制布局,或 JSON.parse 在循环中被反复调用)
- 展开函数节点,能看到完整调用链:A → B → C → 问题函数,有助于判断是哪一层逻辑引入了开销
- 右键函数名 → “Reveal in Sources”,可跳转到对应源码位置(需 sourcemap 正常加载)
用 PerformanceObserver 主动捕获并打印函数名
对难以手动复现的长任务(如后台定时器、滚动中触发),可在代码中监听并输出上下文:
- 监听
longtask类型,获取其attribution字段(包含调用堆栈前几帧,Chrome 120+ 支持) - 结合
performance.getEntriesByType('navigation')获取当前页面状态(如是否在滚动、是否刚完成加载) - 示例:const po = new PerformanceObserver(list => { list.getEntries().forEach(e => { console.warn('长任务', e.attribution?.[0]?.function || 'unknown', e.duration); }); }); po.observe({entryTypes: ['longtask']});
配合 console.time 和函数标记缩小范围
如果火焰图太密集或压缩代码难读,可在可疑逻辑前后加标记:
- 在函数入口用
performance.mark('fn-start'),出口用performance.mark('fn-end'),再measure计算耗时 - 对高频调用函数(如 scroll 处理器、渲染循环),用
console.time('render-frame')快速验证单次执行时间 - 发现某函数稳定在 40–60ms,即使未被面板标为 Long Task,也说明它已逼近帧预算临界点,需优化
注意识别“伪长任务”干扰项
不是所有长条都来自你写的 JS 函数:
- Layout / Paint / GC 块虽在 Main 轨道,但不属于 JS 长任务,不能靠拆分函数解决(需改 CSS、减少重排、控制内存分配)
- 第三方 SDK(如监控脚本、广告代码)可能注入隐藏长任务,用 Bottom-Up → Group by Activity 查看 “Script Evaluation” 占比,再过滤 domain 判断来源
- 异步回调嵌套过深时,调用栈可能被截断,此时要结合
console.trace()在关键点主动打日志补全路径











