前端全链路优化实战(五):从卡顿、白屏到 LCP 和 CLS 的系统打法
性能优化不是把每个技巧都用一遍,而是找到关键路径上的阻塞点,然后减少无效动作。可以把页面加载看成一条生产线:TTFB、关键请求、主线程长任务、资源加载和布局稳定性,任何一个环节堵住都会影响最终体验。

性能优化不是把每个技巧都用一遍,而是找到关键路径上的阻塞点,然后减少无效动作。可以把页面加载看成一条生产线:TTFB、关键请求、主线程长任务、资源加载和布局稳定性,任何一个环节堵住都会影响最终体验。
卡顿:主线程长任务是第一嫌疑人
用户点击按钮后页面迟迟没有响应,常见原因是主线程被长任务占满。浏览器要在同一个主线程上处理脚本执行、样式计算、布局、绘制和用户输入。如果一段 JavaScript 连续执行几百毫秒,用户的点击就只能排队。
优化思路不是简单地“少写 JS”,而是拆任务:
- 把大循环拆成小块,用
setTimeout、requestIdleCallback或任务调度分批执行。 - 对可延后的计算降低优先级,不要抢占用户交互。
- 动画尽量使用
requestAnimationFrame,避免在动画中频繁读写布局。 - 减少同步布局读取,例如反复读取
offsetHeight后又修改样式。 - 对复杂列表使用虚拟滚动或分页渲染。
判断卡顿时,可以结合 INP、Long Task、Performance 面板和用户行为。只看脚本错误通常找不到卡顿,因为卡顿不一定报错。
渲染:重排和重绘来自错误的读写节奏
浏览器渲染大致经历 HTML 解析、CSS 解析、样式计算、布局、绘制、合成。布局和绘制成本高,尤其是在复杂页面里。一个常见反模式是循环中不断读写 DOM:
items.forEach((item) => {
const height = panel.offsetHeight;
item.style.top = `${height + item.index * 20}px`;
});
这类代码可能强迫浏览器反复布局。更好的方式是先批量读取,再批量写入,或者把计算放在内存数据里,最后一次性更新 DOM。
CSS 也会影响渲染。复杂选择器、频繁改变会触发布局的属性、大量阴影和滤镜,都可能带来额外成本。优化渲染时,不要只盯着 JavaScript,也要看样式计算和布局树变化。
TTFB:首字节不只是后端问题
TTFB 表示浏览器发起请求到收到第一个字节之间的时间。它经常被误解为“后端处理时间”。实际上它包含 DNS、TCP、TLS、代理/CDN、服务端处理、网络传输等多个环节。
当 TTFB 异常时,可以按路径拆:
- DNS 是否慢,是否需要预解析。
- TLS 握手是否频繁,连接是否复用。
- CDN 是否命中,回源是否慢。
- 服务端是否等待下游服务。
- HTML 主文档是否被动态渲染拖慢。
- 资源文件是否缓存策略不合理。
优化 TTFB 不能只找后端要结果。前端可以通过预连接、缓存策略、静态化、边缘缓存、减少重定向等方式缩短链路。
白屏与跳出:用户先看到内容比一次加载完更重要
白屏问题的本质是用户在一段时间内看不到有效内容。对于 App 内嵌页,白屏还可能和 WebView 初始化、离线包、热更新、首屏资源加载有关。
优化白屏可以从几个方向入手:
- 首屏关键资源优先加载,非关键资源延后。
- 使用骨架屏或轻量占位,让用户尽早看到结构。
- 对 App 内页面使用离线包或预加载。
- 减少阻塞渲染的 CSS 和 JavaScript。
- 避免首屏依赖多个串行接口。
跳出率和白屏密切相关。用户不一定等页面完全加载,只要第一眼没有内容、按钮不可点、布局突然变化,就可能离开。因此 FCP、LCP、INP、CLS 要一起看,而不是只看某个单点。
字体、图片和布局偏移:视觉稳定也是性能
字体加载会影响文字显示。外部 Web Font 如果体积大、加载慢,可能造成 FOIT 或 FOUT:要么文字暂时不可见,要么字体替换后布局抖动。优化方式包括减少字体数量、使用 font-display、按需子集化、预加载关键字体。
图片通常是 LCP 的重要来源。优化图片时要注意:
- 使用合适尺寸,避免把大图缩小显示。
- 为响应式场景提供多尺寸资源。
- 首屏关键图片提高优先级。
- 非首屏图片懒加载。
- 使用现代格式,例如 WebP/AVIF。
- 明确图片宽高,避免布局偏移。
CLS 关注的是视觉稳定。广告位、动态插入内容、无尺寸图片、字体替换、异步组件都可能导致页面跳动。布局偏移不只是“看起来不舒服”,还可能让用户点错按钮,造成真实业务损失。
工具路径:不要只看 Lighthouse 分数
Lighthouse 很有用,但它不是唯一答案。不同工具适合不同问题:
- Network 面板看请求顺序、大小、缓存、TTFB。
- Performance 面板看长任务、渲染、布局、脚本执行。
- Lighthouse 看通用优化建议和基准分。
- Web Vitals 实际用户数据看真实体验分布。
- 日志系统看问题是否集中在特定版本、设备、渠道。
一个有效的定位路径是:先用线上指标判断影响范围,再用日志锁定样本,再用 Performance/Network 复现细节,最后用灰度指标验证修复效果。这样工具不再是孤立使用,而是全链路中的不同视角。
优化的底层原则
性能优化可以归纳成三句话:
- 减少请求数量:能合并就合并,能缓存就缓存,能延后就延后。
- 降低请求质量问题:避免慢请求、大资源、阻塞资源和不合理缓存。
- 缩短关键路径:让用户先看到、先能操作、先完成核心任务。
不要为了分数而优化,也不要为了技术洁癖而优化。真正有价值的优化,应该能在全链路数据里看到用户体验改善:LCP 下降、INP 改善、CLS 降低、白屏减少、核心转化恢复。性能优化最终不是让页面“看起来更快”,而是让用户更顺畅地完成任务。