一句话回答
总阻塞时间(TBT)是实验室指标:在首次内容绘制到可交互时间之间,对每个超过 50 毫秒的主线程任务,把超出 50 毫秒的部分加总,反映页面加载期间有多不响应。
公式: TBT = Σ(长任务时长 − 50 毫秒)
什么是总阻塞时间?
总阻塞时间(Total Blocking Time,TBT)衡量页面加载期间主线程被阻塞、无法响应用户输入的时间。它把首次内容绘制到可交互时间(Time to Interactive)之间每个长任务(超过 50 毫秒的任务)的「阻塞」部分加起来。
TBT = Σ (每个长任务的时长 − 50 毫秒)
留出 50 毫秒,是因为 50 毫秒以内的任务仍能让浏览器在大约 100 毫秒内响应点击,感觉上是即时的;超出的部分,就是用户不得不等待的时间。
TBT 是实验室指标:Lighthouse 等工具在受控加载中测量它。它对应的现场响应性指标是 Interaction to Next Paint。
计算示例
首次内容绘制之后,主线程上跑了五个任务(示例跟踪):
| 任务 | 时长 | 阻塞时间(时长 − 50 毫秒) |
|---|---|---|
| 框架水合 | 250 毫秒 | 200 毫秒 |
| 统计和标签管理器 | 90 毫秒 | 40 毫秒 |
| 样式重算 | 35 毫秒 | 0 毫秒(不算长任务) |
| 第三方聊天组件 | 120 毫秒 | 70 毫秒 |
| 图片轮播初始化 | 60 毫秒 | 10 毫秒 |
| 合计 | 555 毫秒的工作 | TBT = 320 毫秒 |
只要把水合拆成五段各 50 毫秒,就能单独去掉 200 毫秒 TBT,工作量一点没少,因为每段之间浏览器都能处理输入。
TBT 阈值
Lighthouse 对移动端 TBT 的评级大致为:
| 评级 | TBT(移动端) |
|---|---|
| 良好 | 0–200 毫秒 |
| 需要改进 | 200–600 毫秒 |
| 差 | 超过 600 毫秒 |
Lighthouse 10 及以后,TBT 占性能得分的 30%,权重高于其他任何指标。
TBT、FID 和 INP
| 指标 | 测量方式 | 反映什么 |
|---|---|---|
| TBT | 实验室 | 加载期间主线程阻塞的总时长 |
| 首次输入延迟(2024 年退役) | 现场 | 头一次互动被处理前的延迟 |
| Interaction to Next Paint | 现场(核心网页指标) | 整次访问中所有互动的延迟 |
实验室里 TBT 很高,强烈预示真实用户的 INP 会差,在慢手机上尤其如此。但 TBT 只覆盖加载阶段,INP 还能抓到之后的慢互动。
怎么降低 TBT
- 拆分长任务。 把工作切成小段,中间把主线程让出来(比如用
scheduler.yield()或setTimeout)。 - 少发 JavaScript: 删掉没用的代码,按路由拆分,避免大体积的 polyfill。
- 延后或懒加载第三方脚本,比如聊天组件、A/B 测试和标签管理器,等用户互动或空闲后再加载。
- 少做水合: 局部或渐进式水合、服务端组件、孤岛架构。
- 把繁重工作挪到 Web Worker。
- 避免布局抖动:不要在循环里交替读写布局属性。
在 TapCub 里
TBT 需要受控的实验室运行,TapCub 测量的是真实访问,所以不报告它。性能报表给出 TBT 所预测的现场指标:衡量响应性的 INP,以及 LCP、CLS、首字节时间和首次内容绘制,可以按页面、设备和浏览器看 P75 或 P95。开发时用 Lighthouse 找出长任务,再在 TapCub 里看 INP,确认真实用户感受到了改善。TapCub 脚本本身体积小,加载时不阻塞解析。见核心网页指标和合成监控。
参考资料
- web.dev. Total Blocking Time (TBT).
- Chrome for Developers. Lighthouse: Total Blocking Time.
- web.dev. Optimize long tasks.
这个解释清楚吗?
我们会根据反馈修改和补充这篇内容。
提交没有成功,请稍后再试。
谢谢你的反馈,我们会据此改进这篇内容。你已经反馈过这篇了,谢谢。
