阿里云最近在作活动,低至2折,有兴趣能够看看:
https://promotion.aliyun.com/...
为了保证的可读性,本文采用意译而非直译。javascript
JavaScript 是如何工做的:深刻网络层 + 如何优化性能和安全html
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 12 篇。前端
若是你错过了前面的章节,能够在这里找到它们:java
正如在上一篇关于 渲染引擎 的博客文章中提到的,咱们认为优秀的 JavaScript 开发人员和杰出的 JavaScript 开发人员之间的区别在于,后者不只理解语言的具体细节,并且理解其内部结构和周遭环境。git
想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!github
49年前,一种叫作 ARPAnet 的网诞生了。它是一个早期的 分组交换网络,也是第一个 实现TCP/IP套件的网络。20年后,蒂姆·伯纳斯-李提出了一种“网状结构”的建议,这种结构后来被称为“万维网”。在这 49 年里,互联网走过了漫长的道路,从仅仅两台计算机交换数据包,到超过 7500
万台服务器、38
亿互联网用户和 13
亿个网站。web
"阿帕"(ARPA),是美国高级研究计划署(Advanced Research ProjectAgency)的简称。他的核心机构之一是信息处理(IPTO Information Processing Techniques Office),一直在关注电脑图形、网络通信、超级计算机等研究课题。阿帕网为美国国防部高级研究计划署开发的世界上第一个运营的封包交换网络,它是全球互联网的始祖。chrome
在这篇文章中,咱们将尝试分析现代浏览器使用什么技术来自动提升性能(甚至在你不知道的状况下),接着深刻浏览器网络层。最后,咱们将提供一些关于如何帮助浏览器提升 Web 应用程序性能的建议。编程
现代 Web 浏览器专为快速,高效,安全地提供网络应用/网站而设计。 数百个组件在不一样的层上运行,从流程管理和安全沙箱到 GPU 管道,音频和视频等等,Web 浏览器看起来更像是一个操做系统,而不只仅是一个软件应用程序。segmentfault
浏览器的整体性能由许多大型组件决定:解析、布局、样式计算、JavaScript 和 WebAssembly 执行、渲染,固然还有网络堆栈。
工程师常常认为网络堆栈是一个瓶颈。这种状况常常发生,由于全部资源都须要从网上获取,而后才能解除其他步骤的阻塞。为了使网络层高效,它须要扮演的角色不只仅是一个简单的套接字管理器。它提供给咱们的是一种很是简单的资源获取机制,但实际上它是一个具备本身的优化标准、API 和服务的完整平台。
做为 Web 开发人员,咱们没必要担忧单独的 TCP 或 UDP 数据包、请求格式化、缓存和其余一切问题。整个复杂性由浏览器负责,所以咱们能够将精力集中在咱们正在开发的应用程序上。然而,了解底层的状况能够帮助咱们建立更快、更安全的应用程序。
本质上,当用户开始与浏览器交互时会发生如下状况:
W3C的浏览时序规范(Navigation Timing specification)提供了一个浏览器API,让咱们能够看到浏览器中每项请求的生命周期背后的时序和性能数据。让咱们看看这些组成部分,每一块都是影响最佳用户体验的关键点:
整个网络过程很是复杂,有许多不一样的层,这可能成为瓶颈。这就是为何浏览器努力经过使用各类技术来提升本身的性能,从而使整个网络通讯的影响最小。
先了解一些术语:
JavaScript 和 WebAssembly 不容许咱们管理单个网络套接字的生命周期,这是一件好事!这不只使咱们的省去较多麻烦,并且还可让浏览器自动进行许多性能优化,其中包括套接字重用、请求优先级和后期绑定、协议协商、强制链接限制等。
实际上,现代浏览器在将请求管理周期与套接字管理分离方面作了更多的工做。套接字组织在按源分组的池中,每一个池执行本身的链接限制和安全约束。挂起的请求被排队、排序,而后绑定到池中的各个套接字。除非服务器有意关闭链接,不然同一个套接字能够跨多个请求自动重用!
因为打开新的 TCP 链接须要额外的成本,所以链接的重用自己就带来了巨大的性能优点。默认状况下,浏览器使用所谓的 “keepalive” 机制,它能够在发出请求时节省打开到服务器的新链接的时间。打开新 TCP 链接的平均时间为:
23ms
120ms
225ms
这种架构为其余一些优化提供了可能, 请求能够根据其优先级以不一样的顺序执行。 浏览器能够优化全部套接字的带宽分配,也能够在预期请求时打开套接字。
正如以前提到的,这一切都由浏览器管理,不须要咱们作任何工做,但这并不意味着咱们什么都作不了。 选择正确的网络通讯模式,类型和传输频率,协议选择以及服务器堆栈的调优/优化能够在提升应用程序的总体性能方面发挥重要做用。
有些浏览器甚至更进了一步。 例如,Chrome 能够学习用户的操做习惯来使本身变得更快。 它根据访问的站点和典型的浏览模式进行学习,以便预测可能的用户行为并在用户执行任何操做以前采起措施。 最简单的例子是当用户在连接上悬停时,Chrome 会预先渲染页面, 若是有兴趣了解有关 Chrome 优化的更多信息,能够查看这篇文章 https://www.igvita.com/posa/h...
容许浏览器管理单个套接字还有另外一个很是重要的目的:经过这种方式,浏览器可以对不受信任的应用程序资源执行一致的安全和策略约束。例如,浏览器不容许 API 直接访问原始网络套接字,由于这将使任何恶意应用程序可以任意链接到任何主机。浏览器还强制执行链接限制,以保护服务器和客户端免于资源耗尽。
浏览器格式化全部传出请求,以强制执行一致且格式良好的协议语义,以保护服务器。相似地,响应解码是自动完成的,以保护用户免受恶意服务器的攻击。
传输层安全性协议 (Transport Layer Security, TLS)是一种经过计算机网络提供通讯安全性的加密协议。它在许多应用程序中获得了普遍的应用,其中之一就是 Web 浏览器。网站可使用 TLS 保护服务器和Web 浏览器之间的全部通讯。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。
整个TLS握手包括如下步骤:
“Client hello”
消息,与之一同发送的还有客户端产生的随机值和支持的密码套件。“Server hello done”
消息。Pre-Master Secret
,并使用服务器证书中的公钥对其进行加密,将加密的 Pre-Master Secret 发送到服务器。Pre-Master Secret
。 服务器和客户端均基于预主密钥生成主密钥和会话密钥。“Change cipher spec”
通知,以指示客户端将开始使用新的会话密钥进行散列和加密消息。 客户端还发送 “Server finished”
消息。“Change cipher spec”
,并使用会话密钥将其记录层安全状态切换为对称加密。 服务器向客户端发送 “Server finished”
消息。若是任何验证失败,则警告用户 - 例如,服务器正在使用自签名证书。
同源是指文档的来源相同,主要包括三个方面
如下是一些可能嵌入跨源资源的一些例子:
<script src =“...”> </ script>
的 JavaScript。 语法错误的错误消息仅适用于同源脚本<link rel =“stylesheet”href =“...”>
的CSS。 因为 CSS 的宽松语法规则,跨源 CSS 须要正确的 Content-Type 标头。不一样浏览器可能有不一样的限制<img>
加载图片<video>
和 <audio>
的媒体文件<object>
,<embed>
和 <applet>
的插件<frame>
和 <iframe>
的东西。 站点可使用 X-Frame-Options 头部标识来阻止这种形式的跨源交互以上列表并不是完整,其目的是强调工做中 “最小特权” 的原则。 浏览器仅公开应用程序代码所需的 API 和资源:应用程序提供数据和 URL,浏览器格式化请求并处理每一个链接的整个生命周期。
值得注意的是,“同源策略”并非一个单一律念。相反,有一组相关的机制来限制对 DOM 访问、cookie 和会话状态管理、网络和浏览器的其余组件。
最佳请求是没有从新请求。在发送请求以前,浏览器会自动检查其资源缓存,执行必要的验证检查,并在知足指定条件的状况下返回资源的本地副本。若是缓存中没有可用的本地资源,则发出网络请求,并自动将响应放置在缓存中,以便在有权限的状况下进行后续访问。
管理高效且优化的资源缓存很难。 值得庆幸的是,浏览器帮咱们处理整个复琐事情,咱们须要作的就是确保咱们的服务器返回适当的缓存指令; 要了解更多信息,请参阅 客户端的缓存资源(Cache Resources on the Client)。 这个须要咱们为页面上的全部资源提供了 Cache-Control,ETag 和 Last-Modified 响应头部标志。
最后,浏览器的一个常常被忽视的关键功能是提供身份验证、会话和 cookie 管理。浏览器为每一个源维护独立的 “cookie jars”,提供必要的应用程序和服务器 Api 来读写新的 cookie、会话和身份验证数据,并自动附加上和处理相应的 HTTP 头以代替咱们自动执行整个过程。
用一个简单但有说明性的例子来讲明将会话状态管理推放到浏览器端的便利之处:同一个通过身份验证的会话能够在多个选项卡或浏览器窗口之间共享,反之亦然;单个选项卡中的注销操做将使全部其余打开的窗口中打开的会话失效。
研究完了网络服务,终于到达了应用程序 API 和协议这一步。正如咱们所看到的,底层提供了大量关键服务:套接字和链接管理、请求和响应处理、各类安全策略的执行、缓存等等。每当咱们启动 HTTP 或 XMLHttpRequest 、长期的 Server-Sent Events
或 WebSocket 会话,或打开 WebRTC 链接时,咱们都在与这些底层服务进行交互。
没有单一的最佳协议或 API。 每一个稍微复杂的应用程序都须要根据各类要求混合使用不一样的传输:与浏览器缓存的交互,协议开销,消息延迟,可靠性,数据传输类型等。 某些协议可能提供低延迟传送(例如,Server-Sent Events,WebSocket),但可能不符合其余关键标准,例如在全部状况下利用浏览器缓存或支持有效二进制传输的能力。
原文:
https://blog.sessionstack.com...
个人博客即将同步至腾讯云+社区,邀请你们一同入驻:https://cloud.tencent.com/dev...
你的点赞是我持续分享好东西的动力,欢迎点赞!
干货系列文章汇总以下,以为不错点个Star,欢迎 加群 互相学习。
https://github.com/qq44924588...
我是小智,公众号「大迁世界」做者,对前端技术保持学习爱好者。我会常常分享本身所学所看的干货,在进阶的路上,共勉!
关注公众号,后台回复福利,便可看到福利,你懂的。