DNS 预解析和预连接

时间:2024-12-13 21:06:31

DNS 解析和预连接是 Web 性能优化中的两个重要概念,它们有助于减少页面加载时间和提高用户体验。下面我将分别解释这两个概念,并说明如何在实践中使用它们。

DNS 解析

当用户访问一个网站时,浏览器需要知道该网站服务器的IP地址。由于我们通常使用的是人类可读的域名(例如:www.example.com),所以浏览器需要通过DNS(Domain Name System)查询来获取对应的IP地址。这个过程称为DNS解析。解析完成后,浏览器才能建立与服务器的连接并开始下载资源。

DNS解析是一个相对耗时的过程,因为它涉及到向多个DNS服务器发送请求和等待响应。对于每一个新的域名,浏览器都需要进行一次这样的查询,这可能会显著增加页面加载时间,尤其是在页面中引用了多个不同域的资源时。

如何实现DNS预解析

可以通过在HTML文档的<head>部分添加特定的<link>标签来启用DNS预解析:

<head>
  ...
  <link rel="dns-prefetch" href="//example.com">
  ...
</head>

这里,href属性指定了要进行DNS预解析的域名。请注意,URL前没有协议(http:或https:),这是因为DNS预解析只关心域名,而不涉及具体的协议。

DNS解析过程是如何工作的

DNS(域名系统,Domain Name System)解析过程是将人类可读的域名(如www.example.com)转换为计算机网络使用的IP地址(如203.0.113.23)的过程。这个过程对于互联网的正常运作至关重要,因为它使得用户可以通过易于记忆的名字来访问网站和服务,而不需要记住一系列数字。以下是DNS解析的基本步骤:

1. 客户端请求

当用户在浏览器中输入一个网址并按下回车键时,客户端(如用户的电脑或手机)会向其配置的DNS服务器发起查询请求,询问该域名对应的IP地址。

2. 检查本地缓存

首先,客户端会检查自己的本地缓存是否有之前存储的相关DNS记录。如果存在且没有过期,它可以直接使用这些信息,无需进行后续步骤。

3. 查询递归解析器

如果本地缓存中没有找到相关信息,客户端就会联系递归解析器(通常由ISP提供)。递归解析器负责代表客户端执行所有必要的查询以获取答案,并返回结果给客户端。

4. 查询根DNS服务器

如果递归解析器自身也没有缓存的信息,它会开始从根DNS服务器开始查询。根服务器并不直接保存所有的域名信息,而是知道如何找到*域(TLD,例如.com、.org等)的权威DNS服务器。

5. 查询TLD DNS服务器

根据所查询域名的后缀(如.com),递归解析器接下来会向相应的TLD DNS服务器发送请求。TLD服务器持有其管辖范围内所有二级域名的注册信息,但它不会直接回答具体的IP地址,而是指向能够提供该信息的权威名称服务器。

6. 查询权威DNS服务器

最后,递归解析器会联系到具体负责目标域名的权威DNS服务器。这个服务器拥有该域名的所有相关记录,包括A记录(IPv4地址)、AAAA记录(IPv6地址)、CNAME记录(别名)等,并能提供确切的IP地址给递归解析器。

7. 返回结果

一旦获得了正确的IP地址,递归解析器会将此信息反馈给原始客户端。同时,它可能会缓存这一信息一段时间,以便将来更快地响应相同的查询。

8. 使用IP地址建立连接

有了IP地址之后,客户端就可以通过TCP/IP协议栈与目的服务器建立连接,开始传输数据,比如加载网页内容。

缓存机制

在整个过程中,各个层次的DNS服务器和客户端都会对查询结果进行一定时间的缓存。这不仅提高了未来相同查询的速度,也减轻了整个DNS系统的负担。然而,为了保证信息的新鲜度,每条DNS记录都有一个TTL(Time To Live)值,指明这条记录可以被缓存的时间长度。过了这个时间,就需要重新查询以获得最新的信息。

Chrome浏览器如何获取DNS解析时间

在Chrome浏览器中,你可以通过内置的开发者工具来获取DNS解析时间。以下是具体步骤:

使用开发者工具(DevTools)

  1. 打开开发者工具

    • 按 F12 或 Ctrl+Shift+I (Windows/Linux) / Cmd+Option+I (Mac)。
    • 或者点击浏览器右上角的“更多”菜单(三个点),然后选择“更多工具” > “开发者工具”。
  2. 进入网络(Network)面板

    • 在开发者工具窗口顶部找到并点击“Network”。
  3. 刷新页面或发起请求

    • 为了捕捉新的网络活动,可以重新加载网页或者执行你想要分析的操作。
  4. 检查单个资源的详情

    • 点击列表中的任意一项资源(如HTML、CSS、JS文件等),这将在右侧显示更详细的信息。
    • 在“Timing”部分,你会看到整个请求生命周期的时间线,其中包括了DNS查询所花费的时间(如果适用)。这里会列出各个阶段的具体耗时,比如DNS查找(DNS Lookup)、TCP连接建立(Initial connection)、SSL握手(如果有HTTPS的话),以及实际的数据传输。
  5. 查看概览图

    • 在Network面板上方,有一个图表形式展示所有资源加载过程的时间分布。鼠标悬停在这个图表上的某条记录上,可以看到该资源从开始到完成加载过程中每个阶段的精确时间,包括DNS解析时间。

使用性能(Performance)面板

  1. 切换到性能面板

    • 在开发者工具中选择“Performance”。
  2. 录制性能数据

    • 点击“Record”按钮开始录制,进行你想分析的操作后再次点击停止录制。
  3. 分析结果

    • 录制结束后,Chrome会生成详细的性能报告。在报告中寻找“Main”线程下的网络活动,可以发现DNS查询时间以及其他相关指标。

使用命令行界面(Command Line API)

  1. 打开控制台(Console)

    • 在开发者工具中选择“Console”。
  2. 使用performance.getEntries()

    • 输入performance.getEntries()并运行,它将返回一个包含页面上所有性能条目的数组。你可以遍历这些条目来查找特定资源的DNS解析时间。

通过上述方法之一,你就可以准确地了解Chrome浏览器中某个请求的DNS解析所需的时间。这对于诊断和优化网站性能非常有帮助。

DNS 预连接

DNS 预连接是一种 Web 性能优化技术,它允许浏览器在用户可能访问资源之前提前执行 DNS 查询,并建立TCP和TLS连接。这可以减少当用户实际点击链接或请求资源时的等待时间,因为部分准备工作已经完成。

如何实现DNS预连接

可以通过在HTML文档的<head>部分添加特定的<link>标签来启用DNS预连接:

<head>
  ...
  <link rel="preconnect" href="https://example.com">
  ...
</head>

在这个例子中,我们指定的是一个完整的URL,包括协议(https:),因为 Preconnect 涉及到建立安全连接的过程。

使用建议

虽然DNS预连接有助于提高性能,但应该谨慎使用。过多的预连接可能会导致浪费用户的带宽和其他资源,尤其是在移动设备上。因此,应当仅对那些你确定用户很可能很快就会用到的资源进行预连接。

dns-prefetch 和 preconnect 的区别

dns-prefetchpreconnect 都是HTML <link> 元素的属性值,用于优化网页加载性能,但它们的功能和作用范围有所不同:

dns-prefetch

  • 目的:提前解析DNS。

  • 功能:告诉浏览器尽早解析某个域名的DNS记录,这样当页面中需要请求该域名下的资源时,DNS查询这一步已经完成,可以减少延迟。

  • 适用场景:当你知道页面将来可能会访问一个特定的域名(例如通过脚本或图像引用),但不是立即使用它的时候。提前进行DNS解析可以在用户实际点击链接或加载内容之前准备好。

  • 示例代码

    <link rel="dns-prefetch" href="//example.com">

preconnect

  • 目的:建立连接准备。

  • 功能:除了DNS解析外,preconnect还会让浏览器为指定的资源服务器做更多准备工作,包括TCP握手和TLS协商(如果是HTTPS)。这意味着一旦需要从这个域名下载资源,浏览器就已经完成了大部分的连接设置工作,从而进一步缩短了资源获取时间。

  • 适用场景:如果你确定页面会很快从特定域名下载资源,比如加载关键路径上的CSS文件、JavaScript库或者其他重要资源,那么使用preconnect可以帮助加速这些资源的获取过程。

  • 示例代码

    <link rel="preconnect" href="https://example.com">

主要区别

  1. 操作深度dns-prefetch仅限于DNS解析,而preconnect不仅包含DNS解析还包括TCP连接建立以及可能的TLS握手。
  2. 资源消耗:由于preconnect涉及更多的网络操作,它比dns-prefetch消耗更多带宽和系统资源。因此应该谨慎使用,并确保只对确实需要尽快加载的重要资源进行预连接。
  3. 应用时机:如果只是想加快偶尔使用的第三方服务或者不确定是否会用到的资源,则选择dns-prefetch;若明确即将频繁使用某域名下的资源,则应考虑使用preconnect以获得更好的性能提升。