Performance 面板里怎么定位具体哪段 JS 导致了长任务?

开发者美菊 阅读 34

我在用 Chrome DevTools 的 Performance 面板分析页面卡顿,录制后看到主线程上有个超过 100ms 的长任务,但点进去只看到一堆嵌套的匿名函数和框架代码,根本找不到是我写的哪段逻辑。我试过加 console.log 打点,但 Performance 时间线对不上。

比如下面这个简单的点击处理,实际项目里逻辑更复杂:

<button id="btn">点我</button>
<script>
  document.getElementById('btn').addEventListener('click', () => {
    // 模拟耗时操作
    for (let i = 0; i < 1e7; i++) {}
  });
</script>

有没有办法让 Performance 面板更清晰地显示我自己的函数名或文件位置?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
码农致远
这个问题很常见,Performance 面板默认显示的调用栈确实经常被框架代码淹没。

几个能帮到你的方法:

1. 录制时启用 JavaScript Profiler

在 Performance 面板录制前,勾选右上角的 "JavaScript Profiler" 选项(或者在旧版 Chrome 里是 "Record JS profile")。这个开关打开后,Performance 会记录每个函数的调用栈,展开长任务时能看到具体的函数名而不是匿名函数。

2. 用 Main 线程的 Bottom-up 标签

录制完成后,切换到底部的 "Bottom-up" 视图,这个视图按耗时从高到低排序,而且会显示文件名和函数名。你一眼就能看到哪个函数占用时间最多。

3. 展开 Main 线程的调用栈

在主线程时间线上找到那个长任务块,鼠标悬停或者点击展开。关键技巧是:展开后往深处点,一直点到出现你熟悉的文件名或函数名为止。那些框架代码通常在顶部,真正的业务代码在底部。

4. console.profile() 精准定位

在你的点击处理函数开头加 console.profile('点击处理'),结尾加 console.profileEnd()。然后点击按钮触发,DevTools 的 Memory 面板或 Performance 面板里会生成一个独立的性能报告,直接显示你这段代码的调用栈,清晰得多。

5. 善用 User Timing API

在你的逻辑里埋点:
performance.mark('start-heavy-work');
// 你的耗时逻辑
performance.mark('end-heavy-work');
performance.measure('heavy-work', 'start-heavy-work', 'end-heavy-work');

这样 Performance 面板里会出现你自定义的标记,一眼就能对应上。



实测你那个例子,启用 JS Profiler 后,在 Main 线程里能找到那个箭头函数,名字会显示成 addEventListener 的回调 (index.html:6) 这种形式,比匿名函数好认多了。项目里如果用了压缩,可以考虑 Source Map 配合试试。
点赞
2026-03-17 13:02