HAR(HTTP Archive)是浏览器 Network 面板的录像带。把它读懂,前端慢加载、API 调用失败、首屏卡顿这些问题大多数能在五分钟内定位。
HAR 是什么
一份 W3C 标准的 JSON 文件,结构:
{
"log": {
"version": "1.2",
"creator": { "name": "WebInspector", "version": "537.36" },
"pages": [{ "id": "page_1", "title": "...", "pageTimings": {} }],
"entries": [
{
"startedDateTime": "2026-05-02T10:00:00.000Z",
"time": 1234,
"request": { "method": "GET", "url": "...", "headers": [], ... },
"response": { "status": 200, "headers": [], "content": {} },
"timings": {
"blocked": 50, "dns": 20, "connect": 100, "ssl": 80,
"send": 5, "wait": 800, "receive": 200
}
}
]
}
}
entries[] 里每条对应一次请求。真正的金矿在 timings 字段——它把单次请求拆成 7 段,每段对应一个性能瓶颈类别。
Timing 七段
| 段 | 含义 | 谁的责任 |
|---|---|---|
| blocked | 请求被浏览器排队(连接数上限)或被代理阻塞 | 前端架构(连接复用) |
| dns | 域名解析 | DNS / 浏览器缓存 |
| connect | TCP 三次握手 | 网络层 / 距离 |
| ssl | TLS 握手(包含在 connect 内) | TLS 配置 / RTT |
| send | 把请求字节发出去 | 上行带宽 / 请求体大小 |
| wait | 等待第一字节回来(TTFB) | 后端 / CDN |
| receive | 下载响应体 | 下行带宽 / 响应体大小 |
记住一条原则——这七段加起来约等于 time 字段(总耗时)。看哪段占大头就知道瓶颈在哪。
三个最常见的 timing 模式
模式 1:wait 占 80% — 后端慢
[blocked: 5][dns: 0][connect: 0][ssl: 0][send: 1][wait: 950][receive: 44]
▰▰▰▰▰▰▰▰▰▰
TTFB 长——服务器收到请求字节后,自己处理慢。前端无能为力,给后端同学,让他用链路追踪(trace_id)查慢在哪段——常见是 SQL 慢查询、外部 API 依赖慢、GC 卡顿、反代排队。
模式 2:receive 占 80% — 资源太大或网络慢
[blocked: 5][dns: 0][connect: 0][ssl: 0][send: 1][wait: 50][receive: 944]
▰▰▰▰▰▰▰▰▰▰
字节量大于带宽。先看资源体积——5 MB 的图片在 4G 网络 receive 几秒很正常。优化方向:
- 图片 → 用 WebP / AVIF,压缩 50-80%
- JS bundle → 拆 chunk + tree-shaking
- 字体 → 子集化(用 字体子集化工具)
- 启用 gzip / brotli
- 上 CDN 让用户就近取
模式 3:blocked 占 80% — 连接排队
[blocked: 800][dns: 0][connect: 0][ssl: 0][send: 1][wait: 50][receive: 99]
▰▰▰▰▰▰▰▰
HTTP/1.1 同域名 6 连接上限。看是不是同一时间发了 20+ 请求到同一个域名——前 6 条 blocked 短,后面的请求依次排队,blocked 累加。
修复:
- 切 HTTP/2 —— 单连接多路复用,无 6 上限
- 减请求数:合并 sprite、合 JS bundle、懒加载
- HTTP/1.1 时代用域名分片(cdn1/cdn2/cdn3),HTTP/2 后反而是反模式
瀑布图的视觉读法
把 entries 按 startedDateTime 排序,每条画一条横线(长度 = time),就是瀑布图。关键看时间轴的”墙”——某个时间点之前的请求都完成了,后面的请求才开始——这就是首屏阻塞点。
时间轴 →
0ms 500ms 1000ms 1500ms 2000ms
[document────]
[css────] ← 阻塞渲染
[main.js────] ← 阻塞解析
[api1────]
[api2─────]
[img1────]
[img2────]
[img3────]
[api3──]
↑ 这里出现 FCP
document 加载完后,CSS 和不带 defer/async 的 JS 阻塞 HTML 解析——它们必须先到位浏览器才会画出第一帧。所以瀑布图的时间轴上能直接看到 FCP(First Contentful Paint)的位置:所有 render-blocking 资源完成的那一刻。
找出首屏 critical path
按这条线索读 HAR:
- 第一条 document(HTML)——startTime = 0,整页起点
- head 里的 CSS——必须全部加载完
- head 里的同步 JS(无 defer/async)——也必须全部加载完
- 首屏图片——可见区域内的 img、CSS background
这四类资源中最晚结束的那一条 = 首屏可见时间。其它资源(below-the-fold 图片、analytics、统计、第三方 SDK)都可以异步化,不影响首屏。
经典优化案例
慢站点 5 秒首屏,HAR 显示:
- document 200ms
- 4 个 render-blocking CSS 各 800ms(串行加载)
- 1 个 webfont 1500ms(用
font-display: block默认) - 12 个统计 SDK 同时发,前 6 个秒回,后 6 个 blocked 排队 1500ms
问题——render-blocking 串行 + webfont block 默认。
修复:
- 4 个 CSS 合并成 1 个,并把首屏关键样式
<style>内联到 HTML - webfont 加
font-display: swap,先用 fallback 字体显示 - 12 个统计 SDK 加 async,且尽量晚加载(DOMContentLoaded 后)
修完首屏 5 秒 → 1.5 秒。
HAR 看不到什么
HAR 是请求级粒度,下面这些它看不到:
| 看不到的 | 用什么看 |
|---|---|
| 主线程长任务 / Layout 抖动 | DevTools Performance 面板 |
| 内存泄漏 | DevTools Memory 面板 |
| Service Worker 内部逻辑 | Application → Service Workers |
| WebSocket 帧 / SSE 流 | DevTools 内置(HAR 只记一次”开”,不记帧) |
| 渲染瓶颈(重绘 / 重排) | Performance 面板的 paint / layout 事件 |
| Web Vitals(LCP / CLS / INP) | Lighthouse 或 Performance 面板 |
HAR 是网络层的速览。性能优化深入到 frame 级、render 级、CPU 级,必须切到 Performance 面板。
脱敏分享的注意点
把 HAR 给后端 / 客服 / 三方调试时,记住 HAR 默认包含:
- Cookie——一份完整的会话凭证,对方拿到能假冒你登录
- Authorization 头——Bearer token、Basic 认证密码
- 请求体——POST 表单的密码、订单详情、PII
- 响应体——可能含未脱敏的用户数据
永远不要直接发原始 HAR。本工具的”脱敏导出”会把上面这些字段替换成 <redacted>,剩下 URL / 状态 / 耗时 / Header 名足以定位问题。
快速排障 checklist
拿到 HAR 后五步走:
- ✅ 顶部统计卡看 4xx / 5xx 数 → 不是 0 就先过滤这些请求看错误
- ✅ 按耗时降序看前 5 条 → 抓主要瓶颈
- ✅ 单击慢请求看 Timing → 拆 wait / receive / blocked,归因到后端 / 资源 / 连接
- ✅ 按 startTime 升序看时间轴前 20 条 → 找首屏阻塞资源
- ✅ 需要分享时点脱敏导出 → 剥敏感字段后再发
把这五步固化成肌肉记忆,前端故障定位的时间能从一小时压到五分钟。