dns-prefetch和preconnect的实际行为探索

993 阅读3分钟

使用dns-prefetch和preconnect可以提高页面资源加载效率,其具体表现为:

  • dns-prefetch: 告知浏览器对指定域名进行DNS解析。当后续请求该域名资源时可省掉DNS解析的时间。
  • preconnect: 告知浏览器与指定域名的服务器建立连接。当后续请求该域名资源时,可直接使用已建立好的连接,省掉了 DNS+TCP+TLS 的时间。

实验主题

  1. dns-prefetch 确实让浏览器执行DNS了吗?
  2. preconnect 确实让浏览器建立连接了吗?
  3. dns-prefetch 和 preconnect 确实能节省资源加载时间吗?

实验前置说明

  1. 实验环境:win10,chrome v89,wireshark v3.4.4;实验机器上不要使用任何网络代理(比如常见的ssr梯子)
  2. 当浏览器调用操作系统的socket进行DNS查询时,操作系统会缓存DNS查询结果,且浏览器也会自己再另外缓存一次。因此在每次实验发请求之前要清空操作系统的DNS缓存,并关闭浏览器再重新打开,保证实验的请求能够重新走DNS。
  3. win10系统,在cmd中使用 ipconfig 命令可操作DNS信息:
    • ipconfig /displaydns : 查看DNS缓存
    • ipconfig /flushdns : 清空DNS缓存
  4. 使用chrome访问页面前,要先将devTool打开,并在network面板中选中 "Disable cache" 选项,禁用浏览器缓存。
  5. 实验用的js资源是从百度页面中找到的,大小为 1.6kB,链接为 https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/plugins/every_cookie_4644b13.js
  6. 使用wireshark抓包,过滤器设置如图: wireshark.png
    • 下方的是捕获过滤器,该配置表示: 抓取条件为目标域名是 ss1.bdstatic.com 或者 是由本机的53端口发送的数据(53是众所周知端口中的DNS服务端口)。
    • 上方的是显示过滤器,该配置表示在抓取结果中只显示符合以下条件的: dns查询名称中含 bdstatic.com 或者 目标ip是113.113.73.32(此ip是实验时 ss1.bdstatic.com 域名的ip)。

实验一:dns-prefetch 确实让浏览器执行DNS了吗?

实验页面代码为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="dns-prefetch" href="https://ss1.bdstatic.com">
    <title>Document</title>
</head>
<body></body>
</html>

其中加入了 <link rel="dns-prefetch" href="https://ss1.bdstatic.com">,且页面中不含任何该域名下的资源。

打开wireshark抓包,在cmd中执行 ipconfig /flushdns,打开浏览器并开启devTool(确保network的disable cache选项已选中),访问实验页面,可以看到wireshark抓包:

dns.png

当注释掉dns-prefetch那行代码时,就没有这个DNS请求出现。

由此说明,dns-prefetch 确实会让浏览器对指定域名进行DNS。

实验二 preconnect 确实让浏览器建立连接了吗?

实验页面代码为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="dns-prefetch" href="https://ss1.bdstatic.com">
    <title>Document</title>
</head>
<body></body>
</html>

其中加入了 <link rel="preconnect" href="https://ss1.bdstatic.com">,且页面中不含任何该域名下的资源。

按上面相同步骤访问页面,可以看到wireshark抓包:

connect.png

当注释掉preconnect那行代码时,就没有上图中这些请求出现。

由此说明,preconnect 确实会让浏览器与指定域名的服务器建立连接(完成DNS+TCP+TLS)。

实验三 dns-prefetch 和 preconnect 确实能节省资源加载时间吗?

通过在页面中延迟插入一个加载js资源的<script>元素来统计资源加载时长,测试数据为:

仅加载:128ms/97ms/98ms/90ms/105ms 平均值103.6ms 仅dns-prefetch:53ms/45ms/41ms/42ms/44ms 平均值45ms dns-prefetch + preconnect:28ms/12ms/21ms/12ms/18ms 平均值18.2ms 仅preconnect:14ms/14ms/20ms/13ms/22ms 平均值16.6ms

可见dns-prefetch确实可省掉DNS解析的时间,而preconnect在dns-prefetch的基础上又省掉了TCP和TLS握手的时间,确实有效。

【dns-prefetch + preconnect】和【仅preconnect】的数据基本一致,是由于preconnect建立连接必然要先DNS,所以数据也合情合理。