如何开启页面Trace调试工具的调试模式?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1034个文字,预计阅读时间需要5分钟。
直接按+Ctr+Shift+P(Windows/Linux)或+Cmd+Shift+P(macOS),输入+reload+without+cache+回车,然后按+Ctr+Shift+I打开DevTools,切换到+Performance+面板,点击左上角的圆点按钮开始录制。
常见错误现象:点了录制但没反应——多半是页面没加载完成就点了,或者当前标签页处于后台(浏览器会降频采样)。确保页面已完全加载、标签页在前台、且没开太多其他耗资源的标签页。
- 必须勾选
Network和Rendering复选框,否则看不到请求瀑布和帧率细节 - 录制时间建议控制在 3–8 秒内,太长会导致内存溢出、DevTools 卡死
- 首次录制前清空缓存(
Ctrl+Shift+R),避免缓存干扰真实性能表现
Vue / React 项目里怎么让 Trace 显示组件层级(User Timing API)
默认 Trace 只显示浏览器原生事件(如 Layout、Paint),不显示框架内部逻辑。要看到组件 mount、render 时间,得手动打点。
Vue 3 中可在 onMounted 和 onUpdated 里用 window.performance.mark():
onMounted(() => { performance.mark('MyComponent-mounted'); }); onUpdated(() => { performance.mark('MyComponent-updated'); });
React 中类似,在 useEffect 里调用:
useEffect(() => { performance.mark('MyComponent-mounted'); }, []);
- 标记名必须是合法字符串,不能含空格或特殊符号,否则
performance.getEntriesByName()查不到 - DevTools 的 Performance 面板 → Bottom-up 或 Summary 标签页 → Filter 框输入
mark,就能筛选出所有自定义标记 - 注意不要高频打点(比如在 render 内调用),会显著拖慢 Trace 录制速度甚至崩溃
Trace 导出后怎么分析主线程阻塞(Main Thread Flame Chart)
导出的 .json 文件本身不可读,得重新导入 DevTools 的 Performance 面板(右键 → Load profile)。关键看顶部的 Main 火焰图:横向是时间轴,纵向是调用栈深度,颜色越红代表 CPU 占用越高。
容易被忽略的点:
-
Script Evaluation块持续超过 16ms(即一帧),大概率导致掉帧;超过 50ms 就算“长任务”,用户能明显感知卡顿 - 看到大量
GC Event(垃圾回收)紧挨着 JS 执行块,说明内存分配过猛,可能是循环创建对象或闭包持有大数组 - 若
Parse HTML或Compile Script时间异常高,检查是否有未压缩的巨型 bundle 或内联了大量 JS 字符串
Node.js 后端服务怎么配合前端 Trace 定位首屏慢(Trace Context 透传)
前端 Trace 只能看到浏览器侧耗时,首屏慢如果卡在后端,就得把前后端 trace 关联起来。核心是透传 traceparent header。
前端发请求时加:
fetch('/api/data', { headers: { 'traceparent': '00-' + generateTraceId() + '-' + generateSpanId() + '-01' } });
后端(如 Express)收到后,用同一组 ID 记录日志或打点:
app.use((req, res, next) => { const traceParent = req.headers['traceparent']; // 解析 traceParent 得到 traceId/spanId,写入日志或上报 APM next(); });
- 别自己实现 trace ID 生成,用
@opentelemetry/api的trace.getTracer().startSpan()更可靠 - 如果后端用了 Nginx,记得配置
proxy_set_header traceparent $http_traceparent;,否则 header 会被丢掉 - 前后端时间不同步会导致 trace 时间线错乱,务必校准服务器时钟(NTP)
真正难的不是开启 Trace,而是从一堆 200+ 的火焰图区块里,快速定位那个“看起来正常却拖垮整条链路”的 3ms 函数调用——它往往藏在 Promise.then 的微任务队列深处,不放大时间刻度根本看不见。
本文共计1034个文字,预计阅读时间需要5分钟。
直接按+Ctr+Shift+P(Windows/Linux)或+Cmd+Shift+P(macOS),输入+reload+without+cache+回车,然后按+Ctr+Shift+I打开DevTools,切换到+Performance+面板,点击左上角的圆点按钮开始录制。
常见错误现象:点了录制但没反应——多半是页面没加载完成就点了,或者当前标签页处于后台(浏览器会降频采样)。确保页面已完全加载、标签页在前台、且没开太多其他耗资源的标签页。
- 必须勾选
Network和Rendering复选框,否则看不到请求瀑布和帧率细节 - 录制时间建议控制在 3–8 秒内,太长会导致内存溢出、DevTools 卡死
- 首次录制前清空缓存(
Ctrl+Shift+R),避免缓存干扰真实性能表现
Vue / React 项目里怎么让 Trace 显示组件层级(User Timing API)
默认 Trace 只显示浏览器原生事件(如 Layout、Paint),不显示框架内部逻辑。要看到组件 mount、render 时间,得手动打点。
Vue 3 中可在 onMounted 和 onUpdated 里用 window.performance.mark():
onMounted(() => { performance.mark('MyComponent-mounted'); }); onUpdated(() => { performance.mark('MyComponent-updated'); });
React 中类似,在 useEffect 里调用:
useEffect(() => { performance.mark('MyComponent-mounted'); }, []);
- 标记名必须是合法字符串,不能含空格或特殊符号,否则
performance.getEntriesByName()查不到 - DevTools 的 Performance 面板 → Bottom-up 或 Summary 标签页 → Filter 框输入
mark,就能筛选出所有自定义标记 - 注意不要高频打点(比如在 render 内调用),会显著拖慢 Trace 录制速度甚至崩溃
Trace 导出后怎么分析主线程阻塞(Main Thread Flame Chart)
导出的 .json 文件本身不可读,得重新导入 DevTools 的 Performance 面板(右键 → Load profile)。关键看顶部的 Main 火焰图:横向是时间轴,纵向是调用栈深度,颜色越红代表 CPU 占用越高。
容易被忽略的点:
-
Script Evaluation块持续超过 16ms(即一帧),大概率导致掉帧;超过 50ms 就算“长任务”,用户能明显感知卡顿 - 看到大量
GC Event(垃圾回收)紧挨着 JS 执行块,说明内存分配过猛,可能是循环创建对象或闭包持有大数组 - 若
Parse HTML或Compile Script时间异常高,检查是否有未压缩的巨型 bundle 或内联了大量 JS 字符串
Node.js 后端服务怎么配合前端 Trace 定位首屏慢(Trace Context 透传)
前端 Trace 只能看到浏览器侧耗时,首屏慢如果卡在后端,就得把前后端 trace 关联起来。核心是透传 traceparent header。
前端发请求时加:
fetch('/api/data', { headers: { 'traceparent': '00-' + generateTraceId() + '-' + generateSpanId() + '-01' } });
后端(如 Express)收到后,用同一组 ID 记录日志或打点:
app.use((req, res, next) => { const traceParent = req.headers['traceparent']; // 解析 traceParent 得到 traceId/spanId,写入日志或上报 APM next(); });
- 别自己实现 trace ID 生成,用
@opentelemetry/api的trace.getTracer().startSpan()更可靠 - 如果后端用了 Nginx,记得配置
proxy_set_header traceparent $http_traceparent;,否则 header 会被丢掉 - 前后端时间不同步会导致 trace 时间线错乱,务必校准服务器时钟(NTP)
真正难的不是开启 Trace,而是从一堆 200+ 的火焰图区块里,快速定位那个“看起来正常却拖垮整条链路”的 3ms 函数调用——它往往藏在 Promise.then 的微任务队列深处,不放大时间刻度根本看不见。

