使用JavaScript分析网络特征:测量网络延迟
作为开发人员,我们热衷于使用JavaScript进行开发.无论后端使用何种语言,JavaScript和浏览器都是用户端可用的主要语言平台组合。
JavaScript开发中,我们所知道的网络有什么?
网络有很多层,但我们JavaScript开发最关心的是HTTP,它运行在TCP和IP上(也称为Internet协议套件)。
网络延迟通常是通过网络发送信号并获得响应所需的时间,它通常也称为往返时间或ping时间,因为它是ping命令报告的时间。虽然这对于诊断网络问题的网络工程师来说很有趣,但Web开发人员更关心发出HTTP请求和获得响应所花费的时间。因此,我们将HTTP延迟定义为使最小的HTTP请求成为可能所需的时间,并获得具有无关紧要的服务器处理时间的响应(即服务器唯一做的就是发送响应)。
DNS与我们关心的其他所有内容略有不同,它适用于UDP,通常发生在对JavaScript透明的层上。我们将看到如何最好地确定进行DNS查找所需的时间。
当然,网络还有很多,但是在浏览器中通过JavaScript确定这些特性相对来说比较困难。
使用JavaScript测量网络延迟
我的第一直觉是,测量延迟只需要每次发送一个数据包并对其进行计时。在JavaScript中执行此操作相当容易:
我们启动一个计时器,然后加载一个1×1像素的GIF并测量其onload事件何时触发。GIF本身大小为35字节,因此即使添加了HTTP头,也适合单个TCP数据包。这种类型有效,但结果不一致。特别是,第一次加载图像时,它将比后续加载花费更长的时间,即使我们确保图像没有被缓存。
TCP握手和HTTP KEEP-ALIVE
加载网页或图像或任何其他Web资源时,浏览器会打开与指定Web服务器的TCP连接,然后GET通过此连接发出HTTP 请求。TCP连接和HTTP请求的详细信息对用户和Web开发人员也是隐藏的。但是,如果我们需要分析网络的特征,它们很重要。第一次在两个主机(在我们的例子中是浏览器和服务器)之间打开TCP连接时,它们需要“握手”。这通过在两个主机之间发送三个数据包来实现。
一旦建立连接,它就会保持打开状态,直到两端都通过类似的握手决定关闭它。
当我们通过TCP抛出HTTP时,我们现在有一个HTTP客户端(通常是一个浏览器),它启动TCP连接并发送第一数据包(GET例如,一个请求)。如果我们使用HTTP / 1.1(今天几乎每个人都这样做),那么默认情况下将使用HTTP keep-alive(Connection: keep-alive)。这意味着可以在同一TCP连接上发生多个HTTP请求。这很好,因为这意味着我们减少了握手的开销。
现在,除非我们打开HTTP流水线(并且大多数浏览器和服务器将其关闭),否则这些请求将连续发生。
我们现在可以稍微修改我们的代码以考虑TCP握手的时间,并相应地测量延迟。
使用此代码,我们可以测量延迟和TCP握手时间。TCP连接可能已处于活动状态,并且第一个请求在该连接上完成。在这种情况下,两次将非常接近。在所有其他rtt需要两个数据包的情况下,应该约为66%tcp,这需要三个数据包。
通过使用JavaScript分析网络特征,可以测量网络延迟,这也是算是比较有实际测试。