前端优化:DNS 预解析提升页面速度
Category(分类): Other Status: 持续更新
在网页加载过程中,页面经常需要请求当前站点之外的脚本、字体、图片、统计或 CDN 资源。第一次访问某个源时,浏览器可能需要先解析域名,再建立连接、完成 TLS 握手,最后才能发送 HTTP 请求。DNS 预解析可以把其中的域名解析步骤提前,但它只是一个资源提示,不能保证浏览器一定执行,也不能解决所有网络延迟。
原文发表于 2017 年,示例中的 IE8、百度旧域名和部分浏览器版本已经过时。下面保留原文的优化思路,并补充 preconnect、preload、HTTP/3、隐私和测量方法。
一、DNS 只是连接建立过程的一部分
用户访问 https://cdn.example.com/app.js 时,浏览器通常需要经历类似的过程:
- 从浏览器、操作系统、路由器或本地网络缓存查找 DNS 记录;
- 如果本地没有可用记录,向递归 DNS 解析器查询;
- 递归解析器从权威 DNS 服务器获取记录,并按 TTL 缓存;
- 浏览器获得 IP 地址后,HTTP/1.1 和 HTTP/2 通常建立 TCP 连接并完成 TLS 握手;HTTP/3 使用带集成 TLS 握手的 QUIC 连接;
- 浏览器发送 HTTP 请求并等待服务端响应。
实际实现会受到缓存、连接复用、代理、协议版本和网络条件影响,不应把这套流程理解成每次都严格按顺序执行。浏览器也可能并行进行 DNS、连接和资源解析。
DNS 查询耗时可能从几毫秒到数百毫秒不等,20–120ms 只能作为历史经验范围,不能当成固定常数。即使 DNS 很快,服务器排队、TLS、首字节时间、资源大小或 JavaScript 执行缓慢,也可能是主要瓶颈。

二、使用 rel="dns-prefetch"
dns-prefetch 告诉浏览器:页面很可能很快需要访问这个源,可以提前解析它的域名:
<link rel="dns-prefetch" href="https://cdn.example.com">
它只负责尽早进行 DNS 解析,不会建立 TCP/TLS 连接,也不会下载资源。浏览器可以因为网络状态、节省资源、用户隐私或自身策略而忽略这条提示。
1. 只为真正会用到的第三方源添加提示
适合的对象是页面很快会使用、但不一定能在 HTML 早期确定完整资源 URL 的第三方源,例如图片 CDN、字体 CDN 或统计服务:
<link rel="dns-prefetch" href="https://images.example.com">
<link rel="dns-prefetch" href="https://analytics.example.com">
不要把用户输入、任意跳转地址或大量没有实际请求的域名都放进预解析列表。过多提示会带来额外 DNS 查询和隐私泄露:解析器或第三方可能据此推测用户正在访问的页面功能。
对同源资源通常不需要手动 dns-prefetch,因为浏览器已经在请求当前页面时解析并建立了同源连接;HTTP/2、HTTP/3 和连接复用也会进一步减少重复连接成本。
2. X-DNS-Prefetch-Control 和旧写法
原文使用了下面的写法:
<meta http-equiv="x-dns-prefetch-control" content="on">
它是浏览器相关的控制提示,现代浏览器通常会自行决定是否进行 DNS 预解析,因此一般不需要为了使用 rel="dns-prefetch" 再手动打开。某些隐私敏感场景反而可以在服务端考虑:
X-DNS-Prefetch-Control: off
该控制并非所有浏览器都以完全一致的方式实现,也不应被当作强制安全策略。不要照搬原文中 bdimg.share.baidu.com、hm.baidu.com 等旧 HTTP 示例;第三方域名可能已经变更、停用或不再支持 HTTPS,应以项目当前真实依赖为准。
三、preconnect:不仅预解析,还提前建立连接
如果确定很快就会从某个跨源下载重要资源,preconnect 通常比单独的 DNS 预解析更积极:
<link rel="preconnect" href="https://cdn.example.com">
它可能提前完成 DNS、TCP/QUIC 和 TLS 建连,从而减少真正请求时的等待。但它会消耗连接、TLS 握手和设备资源,比 dns-prefetch 更昂贵。只应对最关键的少数第三方源使用,并通过实际测量确认收益。
可以把 dns-prefetch 作为不支持 preconnect 浏览器的回退,但应使用两个独立的 link 标签:
<link rel="preconnect" href="https://cdn.example.com">
<link rel="dns-prefetch" href="https://cdn.example.com">
不要为了省一行把它们写成同一个标签:
<!-- 不建议:部分浏览器对组合写法的处理存在差异 -->
<link rel="preconnect dns-prefetch" href="https://cdn.example.com">
跨源字体等资源的 crossorigin
字体等资源可能以匿名 CORS 模式请求,预连接时也要匹配实际的凭证模式:
<link rel="preconnect" href="https://fonts.example.com" crossorigin>
是否需要 crossorigin 取决于资源类型和实际请求方式;不要无条件添加,也不要因为预连接而放宽服务端 CORS。
四、preload 与其他提示不要混用概念
如果已经知道完整资源 URL,并且资源对首屏非常关键,应考虑 preload:
<link rel="preload" href="https://cdn.example.com/app.js" as="script">
dns-prefetch:只提前解析域名;preconnect:提前建立到源的连接;preload:提前请求一个已知的关键资源;prefetch:提示浏览器未来可能需要资源,优先级通常较低,不能用来替代首屏资源优化。
不要为所有脚本、图片和字体都 preload,否则会抢占带宽、增加缓存压力并拖慢真正重要的资源。对于首屏 LCP 图片,优先让资源尽早出现在 HTML 中;只有资源发现较晚时才考虑合理使用 preload,并配合 fetchpriority 等手段测量。
五、什么时候值得使用?
可以按下面的原则选择:
| 场景 | 建议 |
|---|---|
| 很快会访问但资源 URL 还不确定的关键第三方源 | 少量使用 preconnect |
| 会访问但不够关键,或者第三方源较多 | 优先考虑 dns-prefetch |
| 已知完整 URL 且属于首屏关键资源 | 评估 preload |
| 只有用户操作后才可能访问 | 通常不要提前连接或解析 |
| 当前页面同源资源 | 通常不需要手动 DNS 预解析 |
| 完全不确定是否会请求的域名 | 不要添加,避免浪费和隐私泄露 |
页面早期确实会加载百度联盟、广告、统计或第三方字体时,预解析可能减少首次请求等待;但应先确认第三方服务稳定、支持 HTTPS、符合隐私要求,并确保页面在第三方服务失败时仍能正常使用。
六、性能和隐私上的代价
1. 预解析不是越多越好
每个提示都可能产生 DNS 查询;preconnect 还可能建立暂时用不到的连接并进行 TLS 握手。太多连接会造成带宽竞争、移动设备耗电和连接队列拥塞。
2. 预解析可能泄露访问意图
DNS 查询会把“页面准备使用哪些域名”的信息暴露给本地网络、DNS 解析器或对应服务商。第三方统计、广告和用户身份相关域名尤其需要审查,不能因为提升几毫秒就忽略隐私合规。
3. 不能代替真正的性能优化
DNS 预解析无法修复:
- 服务器响应慢、缓存命中率低或接口串行等待;
- 图片、脚本过大,压缩和缓存策略不合理;
- 主线程被大型 JavaScript 阻塞;
- 资源发现太晚、渲染路径过长或第三方服务不稳定。
应先减少不必要的第三方依赖、复用连接、启用 HTTPS、HTTP/2 或 HTTP/3、压缩和缓存资源,再决定是否加资源提示。
七、如何验证是否真的有效
不要只凭“感觉加载快了”判断:
- 在 Chrome/Firefox 开发者工具的 Network 面板查看资源的
DNS Lookup、连接、TLS、等待和下载时间; - 使用固定设备、网络和页面版本,对比开启与关闭提示时的冷缓存和热缓存结果;
- 使用 Lighthouse、WebPageTest 或其他实验工具查看首屏、LCP、TTFB 和第三方资源影响;
- 通过
PerformanceResourceTiming和真实用户监控观察不同地区、网络和设备的效果; - 检查页面是否出现多余 DNS 查询、连接失败、CSP/CORS 错误或第三方依赖阻塞。
DNS 预解析通常只会改善第一次连接的一小段时间,用户已经访问过该域名、DNS 命中缓存或连接已经复用时,收益可能接近于零。它没有已知的直接 SEO 加分,价值应以真实用户体验和性能数据为准。
八、上线检查清单
-
dns-prefetch只指向页面确实会访问的 HTTPS 源; - 关键跨源连接经过测量后才使用
preconnect,且数量很少; - 已知的首屏关键资源才考虑
preload,并设置正确的as; - 没有使用已经停用、仅支持 HTTP 或未经审查的旧第三方域名;
- 已评估 DNS 查询、第三方 Cookie、日志和隐私泄露风险;
- 已在冷缓存、热缓存、移动网络和不同地区验证效果;
- 页面在 DNS、CDN 或第三方服务失败时仍有合理降级;
- 没有把资源提示当作可靠性、授权或安全控制。
参考资料
- MDN:
rel="dns-prefetch" - MDN:
rel="preconnect" - web.dev:建立预连接和 DNS 预解析
- MDN:Speculative loading
- 原文历史参考:百度泛用户体验:浏览器的加载与页面性能优化
原文示例中的“IE8 测试效果”和 2017 年编辑时间仅作为文章历史背景保留;实际优化结果必须以当前浏览器、网络和真实用户数据为准。