关键路径优化
关键路径优化:优化渲染关键路径以加快首屏显示。
#type / concept
#status / growing
#tech / dev / frontend
[!info] related notes
- 所属 MOC: 前端性能优化 MOC
- 前置概念: HTTP 缓存
- 并列概念: cdn-acceleration, resource-compression
关键路径优化
一句话定义
关键路径优化是通过减少关键资源数量、缩短关键路径长度和关键渲染字节数,让浏览器尽快完成首屏渲染的性能优化方法。
核心机制 / 工作原理
渲染关键路径
浏览器从接收 HTML 到绘制像素的完整路径:
HTML 文档
→ HTML 解析 → 构建 DOM 树
→ 遇到 CSS → 请求 CSS → 构建 CSSOM
→ DOM + CSSOM → 合成渲染树 (Render Tree)
→ 布局 (Layout / Reflow)
→ 绘制 (Paint)
→ 合成 (Composite)
→ 首屏像素
关键路径上的任何阻塞都会延迟首屏渲染。CSS 阻塞渲染,同步 JS 阻塞解析和渲染。
三类优化策略
| 策略 | 核心思想 | 典型手段 |
|---|---|---|
| 减少关键资源数量 | 让更少的资源阻塞首屏 | 内联关键 CSS、异步加载非关键 CSS、defer/async JS |
| 缩短关键路径长度 | 减少请求往返次数 | preload 关键资源、preconnect 跨域、HTTP/2 多路复用 |
| 缩短关键字节数 | 压缩和精简关键资源 | 压缩 CSS/JS、Tree Shaking、代码分割 |
关键资源清单
- HTML 文档(始终关键)
- 首屏 CSS(阻塞渲染)
- 首屏主图 / 主字体(影响 LCP)
- 首屏关键 JS(可能阻塞解析)
- 首屏必要 API 请求(影响内容可用性)
优化手段详解
| 手段 | 作用 | 使用场景 |
|---|---|---|
<link rel="preload"> | 提前指定要加载的资源 | 首屏关键 CSS、主图、重要字体 |
<link rel="preconnect"> | 提前建立 TCP/TLS 连接 | 跨域 API、CDN 域名 |
<link rel="dns-prefetch"> | 提前解析 DNS | 第三方资源、远端域名 |
| 内联关键 CSS | 消除 CSS 请求往返 | 首屏 above-the-fold 样式 |
| 异步加载 CSS | 阻塞渲染的 CSS 降为非阻塞 | 非首屏样式、打印样式 |
defer / async JS | 解除 JS 对 HTML 解析的阻塞 | 非首屏交互脚本 |
| 懒加载 | 延迟非关键资源 | 非首屏图片、组件、接口 |
| 减少 DOM 深度 | 缩短样式计算和布局时间 | 精简 HTML 结构 |
最小例子
<!-- 内联关键 CSS,消除阻塞 -->
<style>/* 首屏 above-the-fold 样式 */</style>
<!-- 异步加载完整 CSS -->
<link rel="preload" href="/styles/full.css" as="style"
onload="this.onload=null;this.rel='stylesheet'">
<!-- 提前连接第三方域名 -->
<link rel="preconnect" href="https://cdn.example.com">
<!-- 延迟非关键 JS -->
<script defer src="/js/analytics.js"></script>
测量方式
- Lighthouse:查看 “Eliminate render-blocking resources” 诊断
- Chrome DevTools > Network:查看关键资源的瀑布图,识别阻塞链
- Web Vitals:FCP (First Contentful Paint) 和 LCP (Largest Contentful Paint) 是关键路径优化的直接指标
- Coverage Tab:查看 CSS/JS 的未使用比例,指导代码分割
边界与常见误解
- preload vs preconnect:preconnect 只建立连接不下载资源;preload 指定资源并开始下载。两者可配合使用
- 不要 preload 太多:preload 会抢占首屏带宽,过度使用反而拖慢渲染。只 preload 真正关键的 2-3 个资源
- 内联 CSS 不是万能的:内联会增大 HTML 体积,影响缓存效率。只内联首屏关键 CSS,其余异步加载
- 避免 @import:CSS 中的
@import会导致串行请求,用<link>标签替代 - 关键路径不等于首屏:关键路径是浏览器渲染的技术路径,首屏是用户感知;优化关键路径是实现快速首屏的手段