为什么第一个网络通话比后续的通话花费更多的时间?

Ann*_*nah 5 javascript api ajax google-chrome web

我正在尝试了解这种行为,其中第一个网络呼叫所花费的时间比后续网络呼叫的两倍还多。我知道DNS解析不会花费超过5-50ms的时间,并且仅在初始调用中发生。考虑到此信息,第一次呼叫和后续呼叫所花费的时间应该不会有太大差异。

我已经在单独的隐身窗口中用一些著名的URL测试了此行为,每个URL都禁用了缓存,并附上了一些屏幕截图以支持下面的观察。谁能帮助我了解这种行为?

注意:读数是在全速互联网连接中获取的

提前致谢

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

Ale*_*kov 6

经过几次实验,我发现Content Download浏览器请求步骤)部分请求加速了 1.5-2 倍 这看起来像一个原因TCP Slow Start algorithm

正如它所说:

现代浏览器要么同时打开多个连接,要么为从特定 Web 服务器请求的所有文件重用一个连接

这可能是第一个请求比其他请求慢的原因

另外,@Vishal Vijay 做了一个很好的补充:

与服务器进行初始连接握手需要时间(DNS 查找 + 初始连接 + SSL)。浏览器正在为 HTTP 请求创建持久连接并保持打开一段时间。如果在该时间内有针对同一域的任何请求,浏览器将尝试重用相同的连接以获得更快的响应。

  • 谢谢你的回答。这里服务器端缓存不是问题,假设您正在尝试访问已缓存在 CDN 服务器或某些没有任何缓存层的 API 中的文件。第一次从新浏览器或隐身窗口调用这些资源时,第一个 API 调用将比后续调用花费更多时间。这里假设服务器对所有请求都处于理想状态,其中浏览器或网络层中的某些内容为第一个请求增加了额外的延迟。我们正在努力了解它是什么。 (2认同)

Sta*_*kia 6

在某些情况下,它可能是服务器端缓存机制导致后续请求处理得更快,但让我们只讨论浏览器端的东西。

当您将鼠标悬停在瀑布“块”上时,您将获得时间详细信息: Chrome 网络瀑布

以下是每个阶段的快速参考(来自Google Developers):

  • 排队。浏览器在以下情况下对请求进行排队:
    • 有更高优先级的请求。
    • 已经为此源打开了六个 TCP 连接,这是限制。仅适用于 HTTP/1.0 和 HTTP/1.1。
    • 浏览器在磁盘缓存中短暂分配空间
  • 停滞不前。请求可能因排队中描述的任何原因而停止。
  • DNS 查找。浏览器正在解析请求的 IP 地址。
  • 代理协商。浏览器正在与代理服务器协商请求。
  • 请求已发送。正在发送请求。
  • ServiceWorker 准备。浏览器正在启动服务工作者。
  • 对 ServiceWorker 的请求。请求正在发送给服务工作者。
  • 等待(TTFB)。浏览器正在等待响应的第一个字节。TTFB 代表 Time To First Byte。此时间包括 1 次往返延迟和服务器准备响应所用的时间。
  • 内容下载。浏览器正在接收响应。
  • 接收推送。浏览器正在通过 HTTP/2 服务器推送接收此响应的数据。
  • 阅读推送。浏览器正在读取之前接收到的本地数据。

那么传统 HTTP/1.1 场景中的首个请求和后续请求有什么区别呢?

  • DNS 查找:为第一个请求解析 DNS 可能需要更多时间。使用浏览器 DNS 缓存,后续请求的解析速度会快很多。
  • Waiting (TTFB) : 第一个请求必须建立 TCP 连接到服务器。由于 HTTP keep-alive 机制,对同一服务器的后续请求将重用现有的 TCP 连接以防止另一次 TCP 握手,从而与第一次请求相比减少了三次往返时间。
  • 内容下载:由于 TCP 启动缓慢,第一个请求将需要更多时间来下载内容。由于后续请求将重用 TCP 连接,因此当 TCP 窗口放大时,内容的下载速度将比第一个请求快得多。

因此通常后续请求应该比第一个请求快得多。实际上,这导致了一个常见的网络优化策略:为您的网站使用尽可能少的域。

HTTP/2 甚至引入了多路复用以更好地重用单个 TCP 连接。这就是 HTTP/2 将在现代前端世界中提升性能的原因,我们在 CDN 服务器上部署了大量小型资产。