摘要:套接字按池组织,按原点分组,每个池强制实施自己的连接限制和安全约束。待处理的请求排队,优先,然后绑定到池中的单个套接字。
就像我们之前文章中提到的渲染引擎一样,我们认为好的和优秀的JavaScript开发人员之间的区别在于,后者不仅了解语言的基本要素,还要了解其内部原理和周围环境。
历史四十九年前,创建了一个名为ARPAnet的东西。这是一个早期的分组交换网络,也是实现TCP / IP套件的第一个网络。该网络在加州大学和斯坦福研究院之间建立了联系。 20年后,Tim Berners-Lee发布了一个名为“Mesh”的提案,该提案后来更为人称为万维网。在那49年里,互联网已经走过了漫长的道路,从两台计算机交换数据包开始,到达超过7500万台服务器,38亿人使用互联网和1.3B网站。
在这篇文章中,我们将尝试分析现代浏览器采用哪些技术来自动提升性能,并且我们将特别放大浏览器网络层。最后,我们将提供一些关于如何帮助浏览器提升Web应用性能的想法。
概观现代网络浏览器专为快速,高效和安全地交付网络应用/网站而设计。数百个组件运行在不同的层上,从流程管理和安全沙箱到GPU流水线,音频和视频等等,Web浏览器看起来更像是一个操作系统,而不仅仅是一个软件应用程序。
浏览器的整体性能取决于许多大型组件:解析,布局,样式计算,JavaScript和WebAssembly执行,渲染,当然还有网络堆栈。
工程师经常认为网络堆栈是一个瓶颈。这通常是这种情况,因为在解除其他步骤之前,需要从互联网获取所有资源。为了提高网络层的效率,它不仅需要扮演简单的套接字管理员的角色。它作为一种非常简单的资源获取机制呈现给我们,但它实际上是一个拥有自己的优化标准,API和服务的整个平台。
作为Web开发人员,我们不必担心单个TCP或UDP数据包,请求格式化,缓存和其他所有事情。整个复杂性由浏览器处理,因此我们可以专注于我们正在开发的应用程序。但是,了解发生了什么,可以帮助我们创建更快,更安全的应用程序。
实质上,用户开始与浏览器交互时发生了以下情况:
用户在浏览器地址栏中输入一个URL
给定Web上资源的URL,浏览器首先检查本地和应用程序缓存,并尝试使用本地副本来完成请求。
如果缓存无法使用,浏览器将从URL中获取域名,并从DNS请求服务器的IP地址。如果该域被缓存,则不需要DNS查询。
浏览器会创建一个HTTP数据包,说明它请求位于远程服务器上的网页。
数据包被发送到TCP层,在TCP数据包的顶部添加它自己的信息。此信息是维护启动会话所必需的。
然后将数据包交给IP层,主要工作是找出将数据包从用户发送到远程服务器的方式。这些信息也存储在数据包的顶部。
数据包被发送到远程服务器。
一旦收到数据包,就会以类似的方式发送回应。
W3C Navigation Timing规范提供浏览器API以及浏览器中每个请求的生命周期背后的时间和性能数据。让我们来看看这些组件,因为它们在提供最佳用户体验方面起着至关重要的作用:
整个联网过程非常复杂,有许多不同的层次可能会成为瓶颈。这就是为什么浏览器努力通过使用各种技术来提高性能的原因,以便整个网络通信的影响最小。
套接字管理让我们从一些术语开始:
Origin - 应用协议,域名和端口号(例如https,www.example.com,443)
套接字池 - 属于同一Origin的一组套接字(所有主流浏览器都将最大池大小限制为6个套接字)
JavaScript和WebAssembly不允许我们管理单个网络套接字的生命周期,这是一件好事!这不仅可以让我们的手保持清洁,而且还可以让浏览器自动进行大量的性能优化,其中一些包括套接字重用,请求优先级和后期绑定,协议协商,强制连接限制等等。
实际上,现代浏览器会花费更多的时间来将请求管理周期与套接字管理分开。套接字按池组织,按原点分组,每个池强制实施自己的连接限制和安全约束。待处理的请求排队,优先,然后绑定到池中的单个套接字。除非服务器有意关闭连接,否则可以在多个请求中自动重用相同的套接字!
由于新的TCP连接的开通需要额外的成本,因此连接的重复使用对其本身具有很大的性能优势。默认情况下,浏览器使用所谓的“keepalive”机制,这可以节省在发出请求时打开新连接到服务器的时间。打开一个新的TCP连接的平均时间是:
本地请求 - 23ms
横贯大陆的请求 - 120毫秒
洲际请求 - 225毫秒
这种架构打开了其他一些优化机会的大门。这些请求可以根据其优先级以不同的顺序执行。浏览器可以优化所有套接字上的带宽分配,或者可以在预期请求时打开套接字。
正如我之前提到的,这一切都是由浏览器管理的,并不需要我们的任何工作。但这并不一定意味着我们无能为力。选择正确的网络通信模式,传输类型和频率,选择协议以及调整/优化服务器堆栈可以在提高应用程序的整体性能方面发挥重要作用。
有些浏览器甚至更进一步。例如,Chrome可以自我教导自己在使用它时变得更快。它根据访问的网站和典型的浏览模式进行学习,以便在用户做任何事情之前预测可能的用户行为并采取行动。最简单的例子是当用户在链接上悬停时预先呈现页面。如果您有兴趣了解更多关于Chrome优化的信息,请参阅本章的https://www.igvita.com/posa/h...。
网络安全和沙盒允许浏览器管理单个套接字具有另一个非常重要的目的:通过这种方式,浏览器可以对不可信的应用程序资源执行一致的安全和策略约束。例如,浏览器不允许直接API访问原始网络套接字,因为这可以使任何恶意应用程序与任何主机进行任意连接。浏览器还强制执行连接限制,以保护服务器以及客户端免受资源耗尽。
浏览器格式化所有传出请求,以强化一致且格式良好的协议语义来保护服务器。同样,响应解码自动完成,以保护用户免受恶意服务器的侵害。
TLS谈判传输层安全性(TLS)是一种通过计算机网络提供通信安全性的加密协议。它在许多应用程序中广泛使用,其中之一是网页浏览。网站可以使用TLS来保护其服务器和Web浏览器之间的所有通信。
整个TLS握手由以下步骤组成:
客户端向客户端发送“Client hello”消息,以及客户端的随机值和支持的密码套件。
服务器通过向客户端发送“服务器问候”消息以及服务器的随机值进行响应。
服务器将其证书发送给客户端,并可以向客户端请求类似的证书。服务器发送“服务器已完成”消息。
如果服务器已经从客户端请求证书,则客户端发送它。
客户端创建一个随机的预主密钥,并使用服务器证书中的公钥对其进行加密,并将加密的预主密钥发送给服务器。
服务器收到预主密钥。服务器和客户端根据预主密钥生成主密钥和会话密钥。
客户端向服务器发送“更改密码规格”通知,指示客户端将开始使用新的会话密钥进行散列和加密消息。客户端还发送“客户端已完成”消息。
服务器收到“更改密码规范”并使用会话密钥将其记录层安全状态切换为对称加密。服务器向客户端发送“服务器已完成”消息。
客户端和服务器现在可以通过他们建立的安全通道交换应用程序数据。所有从客户端发送到服务器并返回的消息均使用会话密钥加密。
如果任何验证失败 - 例如服务器正在使用自签名证书,则警告用户。
如果两个页面的协议,端口(如果指定了一个)和主机相同,则两个页面具有相同的来源。
以下是可能嵌入跨源的资源的一些示例:
带有