DNS耗时是网站速度测试报告中经常出现的一项指标,它记录的是浏览器从发起域名解析请求到拿到最终IP地址所消耗的时间。虽然单次解析通常只有几十毫秒,但在首次访问、跨地域访问或者DNS配置不佳的场景下,这个数字可能膨胀到几百毫秒甚至数秒,直接拖慢页面的首屏呈现。理解DNS耗时的产生机制,是做好性能优化的基本功之一。

DNS耗时在测速报告中代表什么
在各类速度测试工具中,DNS耗时的名称略有差异。Chrome开发者工具的Network面板里叫 DNS Lookup,WebPageTest中显示为 DNS,curl命令输出的timing明细中对应 time_namelookup 字段。无论叫法如何,它们衡量的都是同一个过程:把一个域名转换成机器可读的IP地址所花费的时间。
需要注意的是,DNS耗时并非每次请求都会产生。浏览器、操作系统和运营商的递归DNS服务器都会缓存解析结果,只有缓存过期后才会真正发起一次完整解析。因此测速时看到的DNS耗时为0或者极小,说明命中了缓存;而首次冷访问时这项耗时往往最明显。做性能分析时,应该以冷缓存和热缓存两种场景分别测量,才能得到完整的数据。
另一个容易误解的点是:DNS耗时只在连接建立之前发生一次,和后续的TCP握手、TLS协商是串行关系。也就是说DNS每多花100毫秒,整个请求的完成时间就直接推迟100毫秒,没有任何并行掩盖的机会,这也是它值得优化的原因。
DNS解析的完整流程与耗时来源
一次完整的DNS解析涉及多个环节。浏览器首先检查自身缓存,未命中则查询操作系统的hosts文件和本地缓存,仍无结果就把请求交给配置的递归DNS服务器(通常是运营商或公共DNS)。递归服务器如果也没有缓存,就需要从根服务器开始,依次查询顶级域名服务器、权威DNS服务器,逐级拿到最终答案并返回给客户端。
耗时就产生在这些环节中。常见的慢因包括:域名TTL设置过短导致缓存频繁失效、权威DNS服务器负载高或配置不当、递归服务器到权威服务器之间的网络距离太远、使用了劣质DNS服务商,以及域名层级过多(比如CNAME链过长)等。其中CNAME链尤其值得注意,每多一层CNAME记录,就多一次完整的查询往返。
可以用dig命令的trace模式直观观察整个解析链路:
dig +trace +all example.ipipp.com # 输出会依次展示: # 1. 查询根服务器,拿到 .com 顶级域的NS记录 # 2. 查询顶级域服务器,拿到域名授权的NS服务器 # 3. 查询权威服务器,拿到最终的A记录 # 每一步的 Query time 就是该环节的耗时
如何测量并定位DNS耗时问题
定位问题的第一步是拿到准确的耗时数据。命令行下推荐使用dig,它输出的Query time就是一次解析花费的毫秒数。多执行几次可以同时观察缓存效果和稳定性:
dig www.ipipp.com | grep "Query time" # 第一次:Query time: 180 msec (冷查询,走完整递归流程) # 第二次:Query time: 0 msec (命中递归服务器缓存)
curl的 -w 参数可以把timing细节打出来,方便和网页整体加载时间做对照:
curl -o /dev/null -s -w "DNS解析: %{time_namelookup}s\nTCP连接: %{time_connect}s\n总耗时: %{time_total}s\n" https://www.ipipp.com
如果数据显示DNS耗时不稳定,比如同一路径下有时20毫秒有时500毫秒,通常是递归服务器或权威服务器出了问题。这时可以对比不同公共DNS的结果,比如分别用223.5.5.5、119.29.29.29和8.8.8.8查询同一域名:
dig @223.5.5.5 www.ipipp.com | grep "Query time" dig @119.29.29.29 www.ipipp.com | grep "Query time" dig @8.8.8.8 www.ipipp.com | grep "Query time" # 某个DNS明显偏慢,说明问题出在递归层;全部偏慢则要检查权威DNS
浏览器端则可以在Chrome开发者工具的Network面板中,把Timing悬停在请求上,查看Connection setup contains中的DNS Lookup数值,配合Disable cache选项可以模拟冷访问场景。
DNS耗时的优化手段
确认问题后,可以从服务端和客户端两个方向优化。服务端最有效的做法是选择一个在全球或目标市场有充足节点覆盖的DNS服务商,权威服务器的地理分布直接决定了递归查询的往返时间。同时合理设置TTL,静态业务的TTL建议不低于300秒,过短的TTL会让缓存形同虚设;需要快速切换IP时再临时调低即可。
减少CNAME层级也很重要。一些CDN或域名服务会叠加多层CNAME跳转,每一层都增加一次查询。能直接给出A记录就尽量直接给出,或者选择支持CNAME flattening(CNAME展平)的DNS服务商,让权威服务器在返回时直接把最终IP附带上,客户端无需再逐级查询。
客户端方向,网页开发中可以用 <link rel="preconnect"> 和 <link rel="dns-prefetch"> 提前触发关键域名的解析:
<!-- 提前完成DNS解析和TCP握手、TLS协商 --> <link rel="preconnect" href="https://cdn.ipipp.com"> <!-- 仅提前做DNS解析,开销更小 --> <link rel="dns-prefetch" href="https://analytics.ipipp.com">
这两行代码放在head标签的靠前位置,浏览器会在解析HTML的早期就并行发起解析,等到真正请求资源时DNS耗时基本为零。对于依赖第三方脚本、字体、统计服务的页面,这个优化收益相当明显。
最后,DNS耗时只是性能拼图的一块,优化时建议配合完整的水合实验数据,观察首字节时间和首次内容绘制的变化,确认优化真正转化为用户可感知的体验提升。一般而言,将冷访问的DNS耗时控制在50毫秒以内、热访问接近0毫秒,就是比较健康的状态。