Featured image of post 使用 DNS 预取和预连接加速资产加载Featured image of post 使用 DNS 预取和预连接加速资产加载

使用 DNS 预取和预连接加速资产加载

通过在 HTML 标头中引入 dns-prefetch 和预连接资源提示来减少连接开销。

介绍

每个外部资源(字体、脚本、图像、API 端点)都需要网络连接。 DNS 解析TCP 握手TLS 协商的开销可能会导致页面加载时间增加数百毫秒。 资源提示dns-prefetchpreconnect 让您告诉浏览器在实际需要资源之前提前执行这些步骤。


连接成本

建立 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低优先级来源
占位符_0DNS + 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

最佳实践

  1. 将预连接限制为 3-6 个源 - 每个源打开一个真实的套接字
  2. 始终为字体和 CORS 资源添加 crossorigin
  3. 不要预先连接到您自己的源 - 浏览器已经这样做了
  4. 分层 dns-prefetch 作为不支持预连接的浏览器的后备
  5. 站点变更后定期与 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-prefetchpreconnect 是省力、高影响的优化,可减少外部资源的连接开销。使用 dns-prefetch 作为许多来源的轻量级提示,并为 3-6 个最关键的第三方来源保留 preconnect。与 preload 和适当的缓存相结合,这些提示可以将页面加载时间缩短数百毫秒。