使用dns-prefetch和preconnect可以提高页面资源加载效率,其具体表现为:
- dns-prefetch: 告知浏览器对指定域名进行DNS解析。当后续请求该域名资源时可省掉DNS解析的时间。
- preconnect: 告知浏览器与指定域名的服务器建立连接。当后续请求该域名资源时,可直接使用已建立好的连接,省掉了 DNS+TCP+TLS 的时间。
实验主题
- dns-prefetch 确实让浏览器执行DNS了吗?
- preconnect 确实让浏览器建立连接了吗?
- dns-prefetch 和 preconnect 确实能节省资源加载时间吗?
实验前置说明
- 实验环境:win10,chrome v89,wireshark v3.4.4;实验机器上不要使用任何网络代理(比如常见的ssr梯子)
- 当浏览器调用操作系统的socket进行DNS查询时,操作系统会缓存DNS查询结果,且浏览器也会自己再另外缓存一次。因此在每次实验发请求之前要清空操作系统的DNS缓存,并关闭浏览器再重新打开,保证实验的请求能够重新走DNS。
- win10系统,在cmd中使用
ipconfig命令可操作DNS信息:ipconfig /displaydns: 查看DNS缓存ipconfig /flushdns: 清空DNS缓存
- 使用chrome访问页面前,要先将devTool打开,并在network面板中选中 "Disable cache" 选项,禁用浏览器缓存。
- 实验用的js资源是从百度页面中找到的,大小为
1.6kB,链接为https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/plugins/every_cookie_4644b13.js。 - 使用wireshark抓包,过滤器设置如图:
- 下方的是捕获过滤器,该配置表示: 抓取条件为目标域名是 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-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抓包:
当注释掉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,所以数据也合情合理。