介绍
每个外部资源(字体、脚本、图像、API 端点)都需要网络连接。 DNS 解析、TCP 握手和 TLS 协商的开销可能会导致页面加载时间增加数百毫秒。 资源提示如 dns-prefetch 和 preconnect 让您告诉浏览器在实际需要资源之前提前执行这些步骤。
连接成本
建立 HTTPS 连接涉及多次往返:
| 步骤 | 延迟(大约) |
|---|---|
| DNS 查找 | 20-120 毫秒 |
| TCP握手 | 1 个RTT |
| TLS 协商 | 2 实时传输时间 |
| 总计 | 3+ RTT |
在 3G 连接(300 毫秒 RTT)上,传输任何数据之前需要近 1 秒的开销。资源提示消除了大部分内容。
DNS 预取
dns-prefetch 提前解析域名:
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
这会在浏览器仍在解析 HTML 的同时启动域的 DNS 查找。当浏览器遇到来自该源的资源时,IP 地址已被缓存。
何时使用: 简单地引用外部域。它是轻量级的——只有 DNS 解析,没有打开连接。
预连接
preconnect 更进一步:它执行 DNS 查找 + TCP 握手 + TLS 协商:
<link rel="preconnect" href="https://api.example.com" crossorigin>
使用 CORS 模式加载的资源(字体、获取请求等)需要 crossorigin 属性。
何时使用: 页面尽快需要的关键第三方来源 - Web 字体提供商、分析端点、CDN。
预连接与预取/预加载
这些提示有不同的用途:
| 提示 | 行动 | 使用案例 |
|---|---|---|
| 占位符_0 | 仅解析 DNS | 低优先级来源 |
| 占位符_0 | DNS + TCP + TLS | 关键的第三方来源 |
| 占位符_0 | 下载+缓存资源 | 未来导航 |
| 占位符_0 | 下载当前页资源 | 当前页面的关键资产 |
想想层次结构:dns-prefetch 最便宜,preconnect 成本更高但节省更多,preload 实际上下载资源。
实用的 HTML 示例
网络字体(最常见的用例)
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>
第三方API
<link rel="preconnect" href="https://api.example.com" crossorigin>
分析和 CDN
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
Cloudflare 和 TTFB 注意事项
如果您使用 Cloudflare 或类似的 CDN,资源提示仍然很有价值。尽管 Cloudflare 提供了快速优势,但新用户的首次连接仍然需要 DNS 和 TLS。添加 preconnect 通过消除连接设置时间来减少 TTFB(第一个字节的时间)。
衡量影响:
<!-- Before optimization -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<!-- After optimization -->
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
用 Lighthouse 衡量影响
Lighthouse 审核 “预连接到所需来源” 下的资源提示。打开 Chrome DevTools → Lighthouse → 运行审核。寻找:
- 机会:预连接到所需的来源
- 预计节省:最多几百毫秒
您还可以使用启用“禁用缓存”的 网络面板 进行手动测试:
// Before vs. after — check connection timing
// Target: < 100ms connection time for preconnected origins
最佳实践
- 将预连接限制为 3-6 个源 - 每个源打开一个真实的套接字
- 始终为字体和 CORS 资源添加
crossorigin - 不要预先连接到您自己的源 - 浏览器已经这样做了
- 分层 dns-prefetch 作为不支持预连接的浏览器的后备
- 站点变更后定期与 Lighthouse 进行审核
<!-- Fallback pattern: both hints for wide support -->
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
结论
dns-prefetch 和 preconnect 是省力、高影响的优化,可减少外部资源的连接开销。使用 dns-prefetch 作为许多来源的轻量级提示,并为 3-6 个最关键的第三方来源保留 preconnect。与 preload 和适当的缓存相结合,这些提示可以将页面加载时间缩短数百毫秒。

