使第二部分:用JavaScript和DOM分析网络特征
我们都听说过JavaScript是很“美”的编程语言,才使得我们的网站栩栩如生,除了这些功能,我们可以操作JavaScript的方法,以确定浏览器中的各种网络特征(之前已发布过文章),同时我们也了解了Web的基础协议如何工作 ,下面我们将介绍DNS,IPv6和NavigationTiming API的新W3C规范。
连接到Internet的每台设备都由称为IP地址的数字地址标识。在开放互联网上看到的两种形式的IP地址是IPv4,它是一个32位数字,通常表示为由点分隔的四个十进制数字序列,例如
80.72.139.101
,IPv6是一个128位数字,表示为一系列由冒号分隔的多个十六进制数字,例如
2607:f298:1:103::c8c:a407
。
这些地址有利于计算机理解;,它们占用固定数量的字节并且可以很容易地处理,但它们很难让人记住。它们对品牌推广也不是很好,并且经常与地理位置或基础设施服务提供商(如ISP或托管服务提供商)绑定。
为了解决这些缺点,人类发明了“ 域名系统 ”。在最简单的形式中,DNS在人类可读的名称和其机器可读地址之间创建映射。
目前,我们将专注于DNS延迟,以及我们如何使用浏览器中的JavaScript来测量它。DNS延迟非常重要,因为浏览器需要对从中下载资源所需的每个唯一主机名执行DNS查找,即使多个主机名映射到同一IP地址也是如此。
测量DNS查找时间
从JavaScript测量DNS查找时间的简单方法是首先使用其IP地址测量主机的延迟,然后使用其主机名再次测量它。两者之间的差异应该给我们DNS查询时间。
这种方法的问题在于,如果浏览器已经对此主机名进行了DNS查找,那么该查找将被缓存,我们将不会真正有所作为。我们需要的是一个通配符DNS记录,以及一个监听它的Web服务器。
在我们查看代码之前,让我们快速了解DNS查找如何使用以下(简化)图表:
从左到右:这里的客户端是浏览器,DNS服务器(通常)是用户的ISP,根名称服务器知道在哪里查找大多数域,以及最后是权威服务器,它是网站所有者的DNS服务器。
这些层中的每一层都有自己的缓存,只要权威服务器的TTL(称为“生存时间”)说它应该存在,该缓存通常就会存在,但并非所有服务器都遵循规范。
通过上面描述,让我们快速描述代码运行原理,我们在这里做的是以下内容:
- 创建一个以我们的通配符域为前缀的随机主机名。这可确保任何人都不会缓存主机名查找。
- 从该主机加载图像并测量加载它所需的时间。
- 从同一主机加载另一个图像并测量加载所需的时间。
- 计算两次测量时间之间的差异。
第一个测量的时间段包括DNS查找时间,TCP握手时间和网络延迟。测量的第二次包括网络延迟。
但是这种方法有两个缺点。首先,它测量最坏情况的DNS查找时间,即如果你的主机名未被任何中间DNS服务器缓存,则执行DNS查找所需的时间。
此外,可能使大多数人难以实现的是设置通配符DNS记录。如果你不控制DNS服务器,这并不总是可行的。许多共享主机提供商不会让您设置通配符DNS记录。在这种情况下,您唯一能做的就是移动托管服务提供商,或至少移动DNS提供商。
测量IPv6支持和延迟
从技术上讲,测量IPv6不应该是一个单独的问题,然而,即使在推出后十年,IPv6的采用仍然相当低。互联网服务供应商一直在阻挠,因为没有太多的网站提供IPv6支持,网站所有者一直拒绝,因为没有太多的用户拥有IPv6支持,他们不确定它将如何影响性能或用户体验。
IPv6测试分为两部分:
- 首先,我们检查是否可以使用其IPv6地址连接到主机,如果可以,我们会测量所需的时间。
- 接下来,我们尝试连接到仅解析为IPv6地址的主机名。
第一个测试告诉我们用户的网络是否可以建立IPv6连接。第二个告诉我们他们的DNS服务器是否可以查找AAAA记录。我们需要按此顺序运行测试,因为如果IP级别的连接失败,我们将无法正确测试DNS。
代码与DNS测试非常相似,除了我们不需要通配符DNS记录:
- 我们首先使用其IPv6地址从主机加载图像。这将检查我们是否可以建立到IPv6地址的网络连接。如果你的网络,浏览器或操作系统不支持IPv6,则会失败并触发onerror事件。
- 如果图像加载,我们知道支持IPv6连接。我们记录以后用于测量延迟的时间。
- 然后我们尝试使用仅解析为IPv6地址的主机名加载映像。重要的是,即使DNS服务器无法处理IPv6,此主机名也不会解析为IPv4地址,或者此测试可能会通过。
- 如果成功,我们知道我们的DNS服务器可以查找并返回AAAA(相当于A的IPv6)记录。我们记录时间。
- 然后继续计算延迟。我们可以将其与IPv4延迟和DNS延迟进行比较。这也是调用任何回调函数来说测试已完成的合适位置。
- 如果任何图像加载触发了一个错误事件或者它们超时,我们会立即终止测试。在这种情况下,任何未运行的测试都将其相应的变量设置为“NA”,表示不支持。
还有其他方法可以在服务器端的帮助下测试IPv6支持,例如,让服务器设置一个cookie,说明它是通过IPv4还是IPv6加载的。这仅适用于测试页面和图像页面位于同一域中的情况。
NavigationTiming API
NavigationTiming API是让JavaScript开发者对浏览器在下载网页的各种状态所花费的时间的详细信息被许多现代的浏览器提供的接口。
以上是我们根据实战经验总结的,如果有其他错误或遗漏的地方,可以在以下留言与大家一起讨论。