Skip to content

Chrome DevTools 与性能分析

Performance 面板、火焰图、长任务定位、Lighthouse 实战

一、Performance 面板概览

1.1 核心区域

┌─────────────────────────────────────────────────────────────────────────┐
│  Performance 面板                                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  [Record] [Reload] [Screenshot]  [CPU 4x] [Network] [Memory]             │
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │  FPS  │  CPU  │  NET  │  主线程火焰图 (Main)                     │   │
│  │       │       │       │  ┌─────┬─────┬─────────────┬─────┐      │   │
│  │       │       │       │  │Script│Layout│ Paint      │ ... │      │   │
│  │       │       │       │  └─────┴─────┴─────────────┴─────┘      │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │  Summary  │  Bottom-Up  │  Call Tree  │  Event Log                 │   │
│  │  选中任务的耗时分布   │  按耗时排序   │  调用栈树   │  事件列表      │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

1.2 录制步骤

  1. 打开 DevTools → Performance
  2. 勾选 Screenshots(可选,便于分析卡顿时刻)
  3. 勾选 Network(可选,看网络与主线程关系)
  4. 点击 RecordReload 开始录制
  5. 执行目标操作(如滚动、点击)
  6. 点击 Stop 结束

二、火焰图解读

2.1 主线程火焰图

  • 横轴:时间线
  • 纵轴:调用栈深度,上层调用下层
  • 颜色
    • 黄色:Script(JS 执行)
    • 紫色:Rendering(Layout、Paint)
    • 绿色:Painting

2.2 识别长任务 (Long Task)

长任务 = 主线程连续执行超过 50ms 的任务

┌────────────────────────────────────────────────────────────┐
│  ████████████████████████████████████████  ← 长任务 (>50ms) │
│  ████  ████  ████  ████  ████  ← 短任务,可被中断           │
└────────────────────────────────────────────────────────────┘
  • 长任务会阻塞输入响应,导致 FID/INP 变差
  • 红色三角标记表示可能影响交互

2.3 常见性能问题

现象可能原因
大片黄色 ScriptJS 执行过长,考虑拆分或 Worker
频繁紫色 Layout强制同步布局,读写 layout 属性交错
长任务内有 Recalculate Style样式计算耗时,减少选择器复杂度
大量 Paint重绘频繁,考虑合成层优化

三、长任务定位与优化

3.1 定位长任务

  1. 在火焰图中找到宽度 > 50ms 的黄色块
  2. 点击展开,查看 Bottom-UpCall Tree
  3. 找到耗时最高的函数

3.2 优化策略

javascript
// ❌ 长任务:一次性处理大量数据
function processAll(items) {
  items.forEach(item => heavyWork(item));
}

// ✅ 拆分:使用 requestIdleCallback 或 requestAnimationFrame
function processInChunks(items) {
  let i = 0;
  function process() {
    const deadline = performance.now() + 16; // 约一帧
    while (i < items.length && performance.now() < deadline) {
      heavyWork(items[i++]);
    }
    if (i < items.length) requestIdleCallback(process);
  }
  requestIdleCallback(process);
}

3.3 使用 Scheduler.yield(实验性)

javascript
// Chrome 108+ 实验性 API
if ('scheduler' in globalThis && 'yield' in scheduler) {
  await scheduler.yield(); // 让出主线程
}

四、内存分析

4.1 Memory 面板

  • Heap snapshot:堆快照,查看对象分布
  • Allocation instrumentation:分配时间线,定位泄漏
  • Allocation sampling:采样分配,低开销

4.2 内存泄漏排查

  1. 打开页面,执行操作
  2. 拍快照 1
  3. 执行可能泄漏的操作(如打开/关闭弹窗)
  4. 手动 GC(点击垃圾桶图标)
  5. 拍快照 2
  6. 选择 Comparison,对比快照 1 和 2
  7. 查看 Detached 的 DOM 节点或未释放的闭包引用

4.3 常见泄漏场景

javascript
// ❌ 泄漏:定时器未清除
const id = setInterval(() => {}, 1000);
// 组件卸载时未 clearInterval(id)

// ❌ 泄漏:事件监听未移除
element.addEventListener('click', handler);
// 组件卸载时未 removeEventListener

// ❌ 泄漏:闭包引用大对象
function createClosure() {
  const bigData = new Array(1000000).fill(0);
  return () => console.log(bigData.length); // bigData 无法释放
}

五、Lighthouse 使用

5.1 运行方式

  • DevTools → Lighthouse 面板
  • 选择 PerformanceAccessibility
  • 选择 MobileDesktop
  • 点击 Analyze page load

5.2 核心指标

指标说明良好值
FCP首次内容绘制< 1.8s
LCP最大内容绘制< 2.5s
TBT总阻塞时间< 200ms
CLS累积布局偏移< 0.1
Speed Index内容填充速度< 3.4s

5.3 常见优化建议

  • Reduce JavaScript execution time:代码分割、懒加载、减少首屏 JS
  • Eliminate render-blocking resources:内联关键 CSS、异步非关键 JS
  • Properly size images:使用 srcset、现代格式 (WebP/AVIF)
  • Avoid long main-thread tasks:拆分长任务

六、Network 面板与性能

6.1 关键请求

  • Waterfall:请求时序,看阻塞关系
  • Priority:请求优先级(High/Medium/Low)
  • Size:传输大小 vs 实际大小(gzip 后)

6.2 性能相关

  • 检查是否有请求阻塞渲染(如同步 script)
  • 检查关键资源是否使用 preload
  • 检查是否有不必要的重复请求

七、Rendering 工具

7.1 常用 overlay

  • Paint flashing:重绘区域闪烁
  • Layout Shift Regions:布局偏移区域高亮
  • Frame Rendering Stats:FPS 显示
  • Scrolling performance issues:滚动性能问题

7.2 使用方式

DevTools → 按 Esc 打开抽屉 → Rendering 标签


八、高频面试题

Q1: 如何排查页面卡顿?

答案:用 Performance 录制,看主线程火焰图,定位长任务(>50ms 的黄色块),用 Bottom-Up 找到耗时函数,拆分任务或使用 Worker。

Q2: 如何排查内存泄漏?

答案:Memory 面板拍两次 Heap snapshot,对比 Detached DOM 或未释放对象;或用 Allocation instrumentation 看分配时间线。

Q3: Lighthouse 的 LCP 和 TBT 分别代表什么?

答案:LCP 是最大内容绘制时间,首屏主要内容加载完成;TBT 是总阻塞时间,主线程被长任务阻塞的总时长。

Q4: 火焰图中黄色、紫色、绿色分别代表什么?

答案:黄色是 Script(JS 执行),紫色是 Rendering(Layout/Paint),绿色是 Painting。

前端面试知识库