通过 Ajax 向同一个 HTTP/2 服务器请求多个资源的最快方式

Posted

技术标签:

【中文标题】通过 Ajax 向同一个 HTTP/2 服务器请求多个资源的最快方式【英文标题】:Fastest way to request many resources via Ajax to the same HTTP/2 server 【发布时间】:2019-01-17 11:30:24 【问题描述】:

感谢 HTTP/2 的 one connection per origin principle,当网页加载时,浏览器可以并行加载许多资源(脚本、图像等),但是脚本应该如何动态地做同样的事情呢?

例如,如果一个脚本创建了 5 个 XHR 对象并对同一个服务器进行并行调用,它们会重用同一个 TCP 连接吗?如果脚本需要通过 Ajax 从同一服务器请求 100 个资源怎么办?它应该创建 100 个单独的 XHR 对象,还是应该创建少量并在每次请求完成时重用它们?如果是,在 HTTP/2 时代有多少是最优的?

一般来说,很难找到关于浏览器在 XHR(以及较新的 Fetch API)中使用 HTTP/2 的确切操作以及浏览器执行操作的最佳方式的底层细节在页面加载时执行,即尽可能快地加载几十个小资源。

【问题讨论】:

【参考方案1】:

例如,如果一个脚本创建了 5 个 XHR 对象并对同一个服务器进行并行调用,它们会重用同一个 TCP 连接吗?

如果浏览器和服务器都支持 HTTP/2,那么是的,它们会自动执行此操作,而无需您对 javascript 进行任何更改。这是关于如何实现 HTTP/2 的一大优点。

在某些情况下它不会使用单个连接,例如未经认证的连接通过另一个连接,当前 Web 套接字回退到 HTTP/1.1(通过一种通过 HTTP/2 is just being standardised 实现的方法)。此外,一些浏览器跨选项卡重用连接,有些则没有。但一般情况下它应该使用相同的连接。

如果脚本需要通过 Ajax 从同一服务器请求 100 个资源怎么办?它应该创建 100 个单独的 XHR 对象,还是应该创建少量并在每次请求完成时重用它们?

您可以发送 100 个请求。服务器通常有限制(100 到 120 很常见),您可以在发送如此多的请求时创建下载争用,因此最好少做一些。 Chrome 在发送如此多的请求时也发现了性能问题,因此故意在 HTTP/2 下限制了一些请求,因此请注意这类事情。更多细节在这里:Google Chrome does not do multiplexing with http2

如果是,在 HTTP/2 时代有多少是最优的?

一个非常有趣的问题 - 没有快速答案!

一般来说,很难找到关于浏览器在 XHR(和较新的 Fetch API)中使用 HTTP/2 究竟做了什么以及浏览器做什么的最佳方式的底层细节在页面加载时,即尽可能快地加载几十个小资源。

同意。而且,由于 HTTP/2 仍然是相对较新的,这也仍在发生很大变化。最好是尽可能地熟悉 HTTP/2 并测试、测试、测试!

【讨论】:

谢谢巴里,很高兴知道浏览器会自动重用。你知道浏览器是否在请求完成后保持连接,例如几秒钟,以防出现新请求?由于我们无法创建无限的 XHR,因此可能会出现连接无法重用的情况,如果浏览器处理不当,仍可能导致许多新的 TCP 连接。 规范 (httpwg.org/specs/rfc7540.html#rfc.section.9.1) 声明“HTTP/2 连接是持久的。为了获得最佳性能,预计客户端不会关闭连接,直到确定不需要与服务器进行进一步通信(例如,当用户离开特定网页时)或直到服务器关闭连接。”从我所见,大多数浏览器似乎都遵守这一点,尽管通常服务器会在 60 秒不活动后重置连接(就像在 HTTP/1.1 下所做的那样)。如果需要,浏览器将重新连接。

以上是关于通过 Ajax 向同一个 HTTP/2 服务器请求多个资源的最快方式的主要内容,如果未能解决你的问题,请参考以下文章

Ajax

AJAX

jQuery通过Ajax向PHP服务端发送请求并返回JSON数据

Ajax

AJAX简述

深入理解Ajax