在介绍DNS预解析前,需要先简单了解下什么是DNS解析。
大多数人是通过域名访问网站,当浏览器从(第三方)服务器请求资源时,必须先将该域名解析为 IP地址,然后浏览器才能向该域名发出请求,域名到IP这一过程称为 DNS解析。
为什么要有DNS预解析
自然是因为DNS解析需要时间,就衍生出了DNS预解析作为一个优化。
当你的网站第一次请求某个跨域域名时,需要先解析该域名(例如页面访问cdn资源,第一次访问需要先解析cdn)。可以在请求的Timing上看到有一个DNS Lookup阶段,而在这个请求之后的其他该域名的请求都没有这项时间支出。
image.png
DNS解析时间可能导致大量用户感知延迟(在移动端可能比较明显),DNS解析所需的时间差异非常大,延迟范围可以从0ms(本地缓存结果)到几秒钟时间(网络极差)。
image.png什么是DNS预解析
DNS 预解析是一项让浏览器主动去执行域名解析的功能。
浏览器试图在用户访问链接之前解析域名,其范围包括文档的所有链接,无论是图片的,CSS 的,还是 JavaScript 等其他用户能够点击的 URL。
因为预读取会在后台执行,所以DNS很可能在链接对应的东西出现之前就已经解析完毕,这能够减少用户点击链接时的延迟。
如何开启DNS预解析
<link rel="dns-prefetch" href="xxx.com">
简单的一行代码就能让支持该特性的浏览器提前解析 DNS。也就是说在浏览器请求资源时,DNS 查询就已经准备好了。
准备了一个例子,copy了掘金logo的地址,预解析该图片所在域名dns。然后在点击切换按钮的时候把当前图片替换成掘金logo。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="https://lf-cdn-tos.bytescm.com/">
</head>
<script>
function replaceImg() {
let img = document.querySelector('#img');
img.src = 'https://lf-cdn-tos.bytescm.com/obj/static/xitu_extension/static/brand.82c24770.svg'
}
</script>
<body>
<img id="img" border="0" src="https://www.runoob.com/images/pulpit.jpg" alt="Pulpit rock" width="304" height="228">
<button onclick="replaceImg()">切换</button>
</body>
</html>
点击切换按钮,查看network该图片请求的Timing,发现少了一个DNS解析阶段。
image.png
再来看看不预解析dns的情况:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<script>
function replaceImg() {
let img = document.querySelector('#img');
img.src = 'https://lf-cdn-tos.bytescm.com/obj/static/xitu_extension/static/brand.82c24770.svg'
}
</script>
<body>
<img id="img" border="0" src="https://www.runoob.com/images/pulpit.jpg" alt="Pulpit rock" width="304" height="228">
<button onclick="replaceImg()">切换</button>
</body>
</html>
结果如下,多了dns解析这一阶段:
image.png
继续点击切换,请求如下,dns解析、建立连接时间(Socket) + SSL认证时间都没有:
image.png
其实就等于preconnect(dns解析、建立连接时间(Socket) + SSL认证时间都提前):
<link rel="preconnect" href="https://lf-cdn-tos.bytescm.com/">
注意
- http页面下所有的a标签的href都会自动去启用DNS Prefetch,也就是说,你网页的a标签href带的域名,是不需要在head里面加上link手动设置的。https页面需要使用meta标签强制开启:
<meta http-equiv="x-dns-prefetch-control" content="on">
- dns-prefetch适用于网页引用了大量其他域名的资源,例如淘宝。
网友评论