Chromium内核原理之Preconnect
《Chromium内核原理之blink内核工作解密》
《Chromium内核原理之多进程架构》
《Chromium内核原理之进程间通信(IPC)》
《Chromium内核原理之网络栈》
《Chromium内核原理之网络栈HTTP Cache》
《Chromium内核原理之Preconnect》
《Chromium内核原理之Prerender》
《Chromium内核原理之cronet独立化》
1.概要
2.实现注意点2.1 连接池(并非所有连接都相同)
2.2 预连接池选择启发式(建议)3.实际应用
1.概要
网络堆栈实现了W3C资源提示预连接规范的闪烁接口,以允许站点开发人员在预期未来请求时请求与服务器的连接。主要用例是:
- 预加载扫描程序无法识别的当前页面的子资源。这可以包括由应用的样式(背景图像,字体)发现的资源以及由脚本(分析信标,广告域等)启动的资源。
- 未来导航中使用的顶级域名。例如,在链接到网址缩短器或点击跟踪器上,然后重定向到实际页面。如果页面知道得到的最终目的地,它可以开始与导航到重定向器并行地启动连接。
问题450682跟踪实施以及实施和实验期间出现的问题。
2.实现注意点
2.1 连接池(并非所有连接都相同)
Chrome为各种不同的协议(http,https,ftp等)维护单独的连接池。此外,管理单独的连接池用于可以传输cookie的连接和不能连接的连接,以防止在确定请求为私有时(例如,阻止cookie到第三方域时)跟踪用户。确定请求将使用哪个连接池是在请求时进行的,并且取决于它的生成环境。顶级导航进入允许cookie的池中,而子资源请求则根据请求的域,页面域和用户的隐私设置分配池。
连接不能从一个池移动到另一个池,因此在建立连接时需要确定将为哪个池分配连接。在TLS连接的情况下,不使用预连接连接的成本可能非常高,特别是在资源有限的移动设备上。
preconnect的初始实现没有考虑私有模式,并且所有连接都在cookie允许的连接池中预先连接,导致未连接的连接未被用于未来请求。
2.2 预连接池选择启发式(建议)
预连接的两个不同用例需要不同的处理来确定连接应该属于哪个连接池。在子资源请求的情况下,应该考虑文档URL并且应该评估相关的隐私设置。在顶级导航的情况下,不应考虑文档URL和连接。没有网站所有者可以提供的提示来指示将需要哪种请求,因此浏览器可以正确猜测。
对于在加载文档时启动的预连接请求(在解析HTML和执行脚本时onload事件之前),Chrome将假定预连接请求将用于将要请求的子资源在当前文档的上下文中,将通过考虑拥有文档的URL来选择连接池。
对于在文档加载完成后启动的预连接请求,Chrome将假定预连接请求将用于将来的页面导航,并且连接在选择连接池时不会考虑当前文档的URL(这实际上意味着连接将在allowed-cookies池中建立。
这确实留下了一些错误猜测的可能情况,但应该处理绝大多数情况。特别:
- 在页面加载完成之前预先连接的顶级导航可能会在错误的连接池中结束,因为将考虑文档的URL。
- 如果请求需要私有连接,则在页面加载完成后预先连接的子资源请求可能会在错误的池中结束。
3.实际应用
预连接链接关系类型用于指示将用于获取所需资源的原点。启动早期连接(包括DNS查找,TCP握手和可选TLS协商)允许用户代理屏蔽建立连接的高延迟成本。
<link rel="preconnect" href="//example.com">
<link rel="preconnect" href="//cdn.example.com" crossorigin>
要启动预连接,用户代理必须运行以下步骤:
- 解析href属性给出的URL。
** 如果成功,请将预连接URL作为结果绝对URL,否则中止这些步骤。
** 如果预连接URL的方案不是“http”或“https”之一,则中止这些步骤。 - 让origin成为preconnect URL的来源。
- 让corsAttributeState成为元素的crossorigin内容属性的当前状态。
- 让凭证成为布尔值设置为true。
- 如果corsAttributeState为Anonymous且origin不等于当前Document的origin,则将凭据设置为false。
- 尝试获取与源和凭据的连接。
用户代理应尽可能尝试启动预连接并执行完全连接握手(HTTP的DNS + TCP,以及HTTPS源的DNS + TCP + TLS),但允许选择执行部分握手(仅适用于HTTP的DNS) ,以及用于HTTPS来源的DNS或DNS + TCP),或由于资源限制或其他原因而完全跳过它。
每个源的最佳连接数取决于协商协议,用户当前连接配置文件,可用设备资源,全局连接限制以及其他特定于上下文的变量。因此,应该打开多少个连接的决定推迟到用户代理。