Skip to content

DNS 预解析是什么?怎么实现?

Posted on:2024年8月10日 at 17:06

DNS优化

在介绍dns-prefetch之前,先要提下当前对于DNS优化主流方法。

一般来说,一次DNS解析需要耗费 20-120ms,所以为了优化DNS,我们可以考虑两个方向:

  1. 减少DNS请求次数
  2. 缩短DNS解析时间dns-prefetch

什么是dns-prefetch?

dns-prefetch(DNS预获取)是前端网络性能优化的一种措施。它根据浏览器定义的规则,提前解析之后可能会用到的域名,使解析结果缓存到系统缓存中,缩短DNS解析时间,进而提高网站的访问速度。

为什么要用dns-prefetch?

每当浏览器从(第三方)服务器发送一次请求时,都要先通过DNS解析将该跨域域名解析为 IP地址,然后浏览器才能发出请求。

如果某一时间内,有多个请求都发送给同一个服务器,那么DNS解析会多次并且重复触发。这样会导致整体的网页加载有延迟的情况。

我们知道,虽然DNS解析占用不了多大带宽,但是它会产生很高的延迟,尤其是对于移动网络会更为明显。

因此,为了减少DNS解析产生的延迟,我们可以通过dns-prefetch预解析技术有效地缩短DNS解析时间。

<link rel="dns-prefetch" href="https://baidu.com/">

dns-prefetch背后原理

当浏览器访问一个域名的时候,需要解析一次DNS,获得对应域名的ip地址。 在解析过程中,按照:

的顺序逐步读取缓存,直到拿到IP地址。

dns-prefetch就是在将解析后的IP缓存在系统中

这样,dns-prefetch就有效地缩短了DNS解析时间。因为,在本地操作系统做了DNS缓存,使得DNS在解析的过程中,提前在系统缓存中找到了对应IP。

这样一来, 后续的解析步骤就不用执行了,进而也就缩短了DNS解析时间。

假如浏览器首次将一个域名解析为IP地址,并缓存至操作系统,那么下一次DNS解析时间可以低至0-1ms

倘若结果不缓存在系统,那么就需要读取路由器的缓存,进而后续的解析时间最小也要约15ms

如果路由器缓存也不存在,则需要读取ISP(运营商)DNS缓存,一般像taobao.combaidu.com这些常见的域名,读取ISP(运营商)DNS缓存需要的时间在80-120ms,如果是不常见的域名,平均需要200-300ms

一般来说,大部分的网站到运营商这块都能找到IP。

那也就是说,dns-prefetch可以给DNS解析过程带来15-300ms的提升,尤其是一些大量引用很多其他域名资源的网站,提升效果就更加明显了

浏览器DNS缓存与dns-prefetch

现代浏览器为了优化DNS解析,也设有了浏览器DNS缓存。

每当在首次DNS解析后会对其IP进行缓存。至于缓存时长,每种浏览器都不一样,比如Chrome的过期时间是1分钟,在这个期限内不会重新请求DNS。

Tip:
每当Chrome浏览器启动的时候,就会自动的快速解析浏览器最近一次启动时记录的前10个域名。所以经常访问的网址就不存在DNS解析的延迟,进而打开速度更快。

dns-prefetch 相当于在浏览器缓存之后,在本地操作系统中做了DNS缓存,个人理解,为的是给浏览器缓存做保障,尽量让DNS解析出本地,以此来做了又一层DNS解析优化。

一般来说,DNS在系统的缓存时间是大于浏览器的。

浏览器与系统DNS缓存时间

TTL(Time-To-Live),就是一条域名解析记录在DNS服务器中的存留时间

国内和国际上很多平台的TTL值都是以秒为单位的,很多的默认值都是3600,也就是默认缓存1小时。

dns-prefetch缺点

dns-prefetch最大的缺点就是使用它太多。

过多的预获取会导致过量的DNS解析,对网络是一种负担。

最佳实践

请记住以下三点:

  1. dns-prefetch 仅对跨域域上的 DNS查找有效,因此请避免使用它来指向相同域。这是因为,到浏览器看到提示时,您站点域背后的IP已经被解析。

  2. 除了link 还可以通过使用 HTTP链接字段将 dns-prefetch(以及其他资源提示)指定为 HTTP标头

Link: <https://fonts.gstatic.com/>; rel=dns-prefetch
  1. 考虑将 dns-prefetch 与 preconnect(预连接)提示配对。

由于dns-prefetch 仅执行 DNS查找,不像preconnect 会建立与服务器的连接。

如果站点是通过HTTPS服务的,两者的组合会涵盖DNS解析,建立TCP连接以及执行TLS握手。将两者结合起来可提供进一步减少跨域请求的感知延迟的机会。如下所示:

<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
<link rel="dns-prefetch" href="https://fonts.gstatic.com/">

Note: 如果页面需要建立与许多第三方域的连接,则将它们预先连接会适得其反。 preconnect 提示最好仅用于最关键的连接。对于其他的,只需使用 <link rel="dns-prefetch"> 即可节省第一步的时间DNS查找。

原文转自:https://fe.ecool.fun/topic/d76e76c3-7400-4c6e-958a-b5f00916d47d