4.2 秒不是一个数字,是四段时间排成的队。
一、4.2 秒的四段构成
周六上午十点,一条工单进来:「首页要转四秒。」他先在自己的机器上打开首页,1.1 秒就渲染完了,于是回了一句「可能是你的网络」。对方发来截图:手机、地铁、信号两格。他打开限速工具,把下行压到 p75 的 1.6 Mbps,冷缓存刷新,秒表停在 4.2 秒。
这次他没有先换图。他把 4.2 秒按发生顺序切成四段,每段只问一句「谁在等」:等服务器首个字节 0.6 秒,等阻塞资源下载与解析 1.8 秒,等首屏最大元素出现 1.2 秒,等浏览器完成布局与绘制 0.6 秒。四段相加正好 4.2 秒,任何优化都必须落到某一段上。
以下情境为教学假设,人物、引语和数字不代表经核实的真实案例。
| 阶段 | 改前 | 在等什么 | 改后 | 省下 |
|---|---|---|---|---|
| TTFB | 0.6 s | 服务器响应与首字节 | 0.4 s | 0.2 s |
| 阻塞资源 | 1.8 s | 字体、同步脚本与样式 | 0.5 s | 1.3 s |
| LCP 资源 | 1.2 s | 首屏大图 | 0.6 s | 0.6 s |
| 渲染 | 0.6 s | 布局与首屏绘制 | 0.3 s | 0.3 s |
| 合计 | 4.2 s | — | 1.8 s | 2.4 s |
四段是排队关系,不是并列关系。 前一段没结束时后一段不会开始;所以先砍哪一段,取决于它后面还压着多少工作。1.8 秒的阻塞段后面排着 1.2 秒的图片,这一段不降,图片再小也轮不到它下载。
桌面 58% 的用户看不到这个数字。这正是问题:他自己的机器、公司网络、热缓存,三个条件都站在快的一边;p75 慢网才是那 42% 移动用户里更常见的一侧。
他最初以为是服务器慢,因为 TTFB 0.6 秒看起来最像「后端问题」。但 0.6 秒只占 4.2 秒的 14.3%,即使压到 0.3 秒,用户仍要等 3.9 秒;真正要动的是后面那三段。
二、412 KB 的分解与责任方
打开网络面板,首屏请求一共 412 KB。按类型分成四堆:JS 214、CSS 41、字体 96、图片 61。这个分法比按文件分更有用,因为每一堆背后是不同的人做出的不同决定。
| 资源 | 体积 | 占比 | 责任方 | 首屏是否必需 |
|---|---|---|---|---|
| JS | 214 KB | 51.9% | 入口包与组件库 | 否,首屏只需 96 KB |
| CSS | 41 KB | 10.0% | 全局样式与组件库 | 部分,可拆到路由 |
| 字体 | 96 KB | 23.3% | 品牌字体三个字重 | 是,但可子集化 |
| 图片 | 61 KB | 14.8% | 首屏插画与头像 | 是,可换格式 |
| 合计 | 412 KB | 100.0% | — | — |
JS 的 214 KB 是最大的一堆,但它不是「写了 214 KB 代码」,而是把设置页、导出页与富文本编辑器全打进了同一个入口包;首页真正用到的只有外壳、列表与登录态,约 96 KB。
字体 96 KB 是三个字重,每个 32 KB。品牌字体由设计稿决定,问题不在用不用,而在于整包中文字库被完整下载,首屏实际只用得到几百个字。
图片 61 KB 里,首屏插画 41 KB、头像 20 KB。头像原图 400 px,显示尺寸 40 px,等于多传了一百倍的像素。
责任方要写到决定,不能写到技术。 「JS 太大」没人认领;「入口包把三个非首屏页面打进来了」才对应一个可以改的选择。
三、三项动作与 168 KB 的新分解
三项动作按「省下的秒数 ÷ 投入的小时」排序,另有一项 CSS 拆分是拆包顺带完成的:字体子集化最便宜,路由拆分收益最大,图片格式最确定。
| 动作 | 改前 | 改后 | 省下 | 做法 |
|---|---|---|---|---|
| 路由级拆分 | 214 KB | 96 KB | 118 KB | 非首屏页面按路由懒加载 |
| 字体子集化 | 96 KB | 24 KB | 72 KB | 三个字重各 32 KB 压到 8 KB |
| 图片换格式 | 61 KB | 20 KB | 41 KB | WebP 加按容器尺寸出图 |
| CSS 按路由拆 | 41 KB | 28 KB | 13 KB | 去掉未使用组件的样式 |
| 合计 | 412 KB | 168 KB | 244 KB | — |
路由级拆分把入口包从 214 KB 降到 96 KB,其余页面按路由懒加载;设置页 60 KB、导出页 45 KB、富文本编辑器 13 KB,合计 118 KB 从此不进首屏。拆包顺带按路由拆了 CSS,41 KB 降到 28 KB。
字体子集化把三个字重各压到 8 KB,合计 24 KB;常用汉字与拉丁字母进子集,生僻字回退系统字体。配合 preload 与 font-display,阻塞段从 1.8 秒降到 0.5 秒。
图片换 WebP 并按容器尺寸出图,61 KB 降到 20 KB;首屏插画从 41 KB 到 16 KB,头像从 20 KB 到 4 KB。LCP 资源段从 1.2 秒降到 0.6 秒。
TTFB 那 0.2 秒不在这三项动作里:首页原本串行等两次接口,合并成一次后省下 0.2 秒,与查询篇同源,本文不展开。渲染段从 0.6 秒到 0.3 秒,则是更少的 CSS 与 JS 解析换来的。
三项动作并非互斥,但顺序会影响复测。先拆包再量字体,阻塞段的数字才是干净的;先换图再拆包,LCP 的改善会被字体挡住,容易误判成「换格式没用」。
新分解是 168 KB = 96 + 28 + 24 + 20,四段耗时是 1.8 s = 0.4 + 0.5 + 0.6 + 0.3。
四、复算 244 KB 与 5 小时
244 KB 在 1.6 Mbps 下是 1.22 秒的纯传输时间,但 LCP 实际省了 2.4 秒。差额来自阻塞:字体不再挡住渲染,图片提前 0.6 秒开始下载,省下的时间不是线性叠加的。
三项动作的性价比并不平均。字体用 72 KB 换 1.3 秒,图片用 41 KB 换 0.6 秒,JS 用 118 KB 换来的阻塞与解析下降藏在 0.5 秒里。若只做图片,图片提前下载完也要等字体,改善有限;上一篇只压了 40% 的字节,连 0.1 秒都没换到。
5 小时是这一项的预算上限,占全年 40 小时的 12.5%。它买到的不是「分数更好看」,而是 42% 的移动用户在慢网下少等 2.4 秒。
复测要回到同一台低端手机上。开发机的 CPU 明显更快,同样的 168 KB 会给出过于乐观的渲染段;在真机上,0.3 秒可能要打个折扣。
复算:
改前首屏 = JS 214 + CSS 41 + 字体 96 + 图片 61 = 412 KB
改后首屏 = JS 96 + CSS 28 + 字体 24 + 图片 20 = 168 KB
合计省 = 412 − 168 = 244 KB
分项省 = 118 + 13 + 72 + 41 = 244 KB
削减比例 = 244 ÷ 412 ≈ 59.2%
LCP 改前 = 0.6 + 1.8 + 1.2 + 0.6 = 4.2 s
LCP 改后 = 0.4 + 0.5 + 0.6 + 0.3 = 1.8 s
LCP 省 = 4.2 − 1.8 = 2.4 s;其中阻塞段 1.8 − 0.5 = 1.3 s
慢网传输 = 1,600 kbps ÷ 8 = 200 KB/s
244 ÷ 200 = 1.22 s;168 ÷ 200 = 0.84 s
投入占比 = 5 h ÷ 40 h = 12.5%
合计:省 244 KB、2.4 s,花 5 h。
先做字体,再做拆包,最后换图。 顺序反了不会错,只是同样的 5 小时买不到同样的 2.4 秒。
五、行动清单与复算验收
这一项一个人做,5 小时够;按下面的顺序,每一步都有可验收的产物。
- 用 p75 慢网与冷缓存复现一次首屏,记下 4.2 秒的四段耗时。
- 按 JS、CSS、字体、图片四类导出首屏清单,确认合计 412 KB。
- 找出入口包里不属于首屏的路由,列出可拆出的体积。
- 统计首屏实际用到的字符集,生成字体子集并保留回退方案。
- 按容器尺寸重新导出首屏图片,记录格式与像素变化。
- 复测新分解,确认 168 KB 与 LCP 1.8 秒,并分项对账 244 KB。
- 把四项预算写进发布检查,首屏传输超过 200 KB 时阻断。
- 记下 5 小时的实际用时,下一轮按收益重排顺序。
验收标准:你能指着 412 KB 的四项说出各自的责任方,并在 168 KB 的新分解里指出哪一项省得最多、为什么;说不清,说明首屏还只是一张瀑布图。
使用边界与实操验收
本文只处理首屏的传输体积与阻塞,不讨论具体打包器的配置;构建细节归前端专题 。
缓存与 CDN 不归本文:三层 TTL 与写后失效是第五篇的内容,首屏体积和缓存命中是两笔账。
测量口径必须固定:p75、下行 1.6 Mbps、冷缓存、同一设备档。换了任一条件,4.2 秒与 1.8 秒都不可比。
字体子集化有代价:生僻字与用户自定义名称会回退,回退字体要单独看过,不能只在常用字上验收。
拆包会增加请求数。HTTP/2 下通常划算,但不要把首屏关键路径拆成十几个小文件,否则排队又回来了。
不要用实验室分数替代 RUM。Lighthouse 100 分与 42% 移动用户的真实等待是两件事,前者只说明测试机很快。
5 小时是上限,不是配额;若品牌字体本来就是系统字体,这一项应缩到 3 小时以内,把时间让给查询。
首屏变快不等于产品变快,列表页与导出各有一本账,下一篇先算查询次数。
关键参考与核验范围
- MDN Web Performance :用于核对首屏指标与性能数据的组织方式。
- MDN LargestContentfulPaint :用于核对 LCP 的四段构成与测量口径。
- MDN Resource Timing API :用于核对资源体积与各阶段耗时的采集方式。
- MDN HTTP Compression :用于核对传输压缩对首屏体积的影响。
以上链接于 2026-10-26 实测可公开访问;未核验版本、功能范围与政策更新。核验日期:2026-10-26。
范围上只讨论首屏的体积分解、阻塞与三项前端动作,不讨论构建工具选型、图片编码算法与 CDN 配置。
系列导航
- 上一篇:先测再改:RUM、慢查询日志与一次改错的优化
- 下一篇:数据库:一千二百次查询、三个索引与 8 秒的列表页
- 回到目录:一个人的性能与账单:4.2 秒的首屏、一千二百次查询与每月 210 美元
- 相关阅读:首屏与信息架构:一页只回答一个问题
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。