性能优化最常见的失败方式,是在没有测量之前就开始改。改了一圈,分数没动,或者动了又弹回去。
一、三个指标分别在说什么
- LCP(最大内容绘制):用户看到“主要内容”花了多久
- INP(交互到下一次绘制):用户操作后,界面多久给出反馈
- CLS(累积布局偏移):页面元素有没有在用户眼皮底下乱跳
它们对应三种不同的体验问题:加载慢、响应卡、页面抖。
二、LCP:先找“那一个元素”
LCP 只关心一个元素——视口内最大的那块内容。优化第一步永远是:确认它是谁。
常见元凶与对策:
- 首图太大:换格式(WebP/AVIF)、按尺寸裁剪、预加载
- 首图被懒加载:这是最常见的自伤。首屏图加了
loading="lazy",LCP 会被推迟到滚动或脚本执行之后 - 阻塞渲染的 CSS/JS:拆分关键路径,非关键资源延后
- 字体阻塞文本:
font-display: swap+ 预加载,或使用系统字体栈 - TTFB 高:缓存、边缘渲染、减少重定向
注意:不要对首屏图用懒加载。正确做法是首图 fetchpriority="high" 直接加载,其余资源懒加载。
三、INP:主线程被谁占住了
INP 差,通常是因为长任务。来源包括:
- 大型 JS 包在启动时同步解析执行
- 一次性渲染上千个 DOM 节点
- 复杂的同步计算
- 第三方脚本(统计、客服、广告)
对策:
- 拆分长任务,用
requestIdleCallback/setTimeout切片 - 列表虚拟化,分批渲染
- 把重计算放进 Web Worker
- 第三方脚本延迟加载或干脆去掉
四、CLS:给每个元素“预留位置”
CLS 的根因几乎总是:内容插入时没有占位。
- 图片没有
width/height→ 加载后撑开 - 广告位、嵌入内容没有固定尺寸
- 字体切换导致行高变化
- 顶部突然插入通知条
解决办法很朴素:用 CSS 把空间先占住。aspect-ratio、固定高度容器、骨架屏都能显著改善。
五、测量:实验室与真实用户
- 实验室(Lighthouse)适合定位与回归,但不代表真实分布
- 真实用户监控(RUM)才能看到长尾:低端机、弱网、老浏览器
一个常见误区是只看平均值。性能问题往往集中在少数用户身上,看 P75/P95 比看均值更有意义。
六、优先级建议
如果只能做一件事:先修 TTFB 和首图。这两项通常贡献了 LCP 的大部分。
如果能做三件事:TTFB、首图、主线程长任务。INP 的改善对“感觉流畅”最直接。
CLS 通常最容易修,收益也稳定,适合作为快速见效的起点。
结语
性能优化不是“把所有东西都变小”,而是让关键路径更短、让非关键路径让路。先测量,再动手,最后用真实用户数据确认——顺序错了,努力就会白费。
评论 (0)