在本文中,让我们看一下预连接Preconnect——它们是什么、为什么以及如何使用它们,以及审计和扩展它们的最佳实践。
什么是预连接?
预连接是一种资源提示,它告诉浏览器与浏览器尚未确定需要建立的域建立主动HTTP连接。创建HTTP连接需要很多步骤,包括:
- 进行DNS查找。
- 连接TCP。
- 协商安全的TLS连接。
这可能需要数十甚至数百毫秒。预连接提高了性能,因为当浏览器确实意识到它需要建立一个连接来下载资源时,那个连接已经发生了!
示例和真实案例研究
让我们看一个例子。下面的屏幕截图显示了来自Google的CSS文件请求:
此资源稍后会在瀑布中发现,并且现有的HTTP连接不存在。浏览器知道它需要下载这个CSS文件,但首先它必须完成DNS查找,然后创建TCP连接,最后协商一个加密的TLS连接。这些会在请求CSS文件之前增加大约100毫秒的延迟。我们可以通过在HTML文件的<head>中添加预连接资源提示来优化这一点,如下所示:
<link href="https://fonts.googleapis.com/">
我们可以在下面的瀑布截图中看到结果。预连接提示指示浏览器主动连接到Google字体域。当浏览器稍后发现它需要请求的CSS文件时,已经建立了连接。这使得CSS文件可以立即下载,将整个瀑布流向左移动:
这是一个很好的例子,但是有哪些真实世界的例子来说明预连接的好处呢?
- 一家在线商店通过使用产品图像目录预连接到域,将他们的关键绘画指标提高了500毫秒至1秒以上。
- Aaron Peters 有一个示例,其中预连接将CDN Planet的初始渲染性能提高了大约10%。
下面这个例子,这是一家媒体网站,拥有大量用于各种第三方域的JavaScript。通过分析他们的站点并实施资源提示(例如预连接和预加载),将交互时间提高了37%,从12.8秒的中位数降低到7.9秒。
一般来说,资源提示——尤其是预连接——是所有网站都应该考虑的。
如何使用预连接来提高性能
鉴于上述令人印象深刻的收获,我知道您一定在想什么:
如果预连接资源提示提高了整体性能和用户体验,为什么我不预连接到我的网站使用的所有域?
不幸的是,这会损害性能。为什么?这很简单:浏览器使用大量复杂的逻辑来决定需要下载什么以及何时下载,因此页面可以尽快呈现并响应访问者。(如果你想要所有书呆子的细节, Pat Meenan已经详尽地记录并展示了它。)
使用资源提示的站点本质上是要求覆盖浏览器通常会执行的操作。如果使用不小心,这可能是不同性能问题的根源。
过多的预连接提示
浏览器会限制它们将维持的HTTP连接数。使用过多的预连接资源提示将限制浏览器进行所需的连接。实际上,过多的预连接会损害性能。
一个好的经验法则是不超过6-8个预连接资源提示。
预连接到未使用的域
唯一比进行太多预连接更糟糕的是,要求浏览器预连接到一个甚至没有使用过的域!然而,这可能非常普遍。站点更改其内容的来源,或者在不删除该域的预连接资源提示的情况下停止使用第三方提供商。预连接到未使用的域会以两种方式导致性能问题:
- 未使用的预连接会损害浏览器,因为它们会阻碍与其他域的连接。
- 即使未使用,打开的TCP和加密的TLS连接也会使用服务器资源。Akamai研究发现,多达6%的加密HTTP连接实际上并不发出任何请求。
过早关闭的预连接
因为浏览器限制了它们将保持的HTTP连接数,所以如果10秒内没有请求发生,浏览器将关闭HTTP连接。当 预连接提示告诉浏览器打开到域的HTTP连接,但在10秒内没有向该域发送请求时,会发生Premature Preconnect 。浏览器然后关闭此连接,只有在需要从该域请求资源时才需要再次连接。这很糟糕,原因有两个:
- 过早的预连接会损害浏览器,因为它会阻碍与其他域的连接。
- 一旦实际遇到对该域的请求,浏览器必须打开另一个到该域的连接。因此,进行预连接根本没有任何净收益!
Safari的rel资源提示问题
许多站点采用了在同一 <link> 标记内同时指定预连接提示和 dns-prefetch 提示的模式,如下所示。(有关详细讨论,请参阅我们的DNS预取资源提示指南。)
<link href="https://example.com/">
这种做法之所以开始,是因为浏览器支持的资源提示类型不同。截至2020年,支持预连接的浏览器多于支持DNS预取的浏览器,所有支持DNS预取的主流浏览器也支持预连接。
在同一个<link>标签内指定两个不同的资源提示确实没有什么好处,实际上,这样做有很大的负面影响。Safari只允许在<link>标签的rel属性中指定一个资源提示 。在同一个rel属性中指定两个提示会导致Safari完全跳过<link>标记,并且不会尝试任何一个资源提示。
实际上,指定多个资源提示会禁用Safari的提示!相反,您应该只使用<link>提示。
何时使用预连接提示
通常,应为以下内容提供预连接提示:
- 后来在瀑布中发现的领域
- 具有对页面呈现或交互至关重要的资源的域
- 具有大量请求或下载大量内容的域
很好的例子包括:
- 关键渲染路径中需要的具有CSS和JS包的其他域
- Web字体由CSS引用,需要下载
- 用于初始加载或呈现页面的API端点的第一方域
一旦确定了应该预连接哪些域, 您仍然需要对其进行测试! 仅仅因为某些东西应该可以改善您网站的性能或体验,并不意味着它会。确保始终进行测试以验证:
- 使用工具来衡量您的表现。
- 实施你的改变。
- 比较“之前”和“之后”的性能指标。
预连接资源提示的最佳实践
我们已经看到使用预连接资源提示有很多好处,但如果使用不当,也会有很多缺陷会影响性能。这意味着审核页面如何使用资源提示以确保您遵循所有最佳实践非常重要。
- 首先,确定页面当前正在使用的所有预连接资源提示。您将需要在基本HTML页面中查找<link>标记,以及链接: 也可以包含资源提示的HTTP标头。还要记住,包含资源提示的链接标头可以出现在基本HTML页面之外的其他响应中!
- 使用上述指南,确定应预连接哪些域。它们是否在页面已经使用的提示列表中?如果不是,为什么不呢?
- 您是否使用超过6-8个预连接?如果是这样,那就太多了,您应该考虑删除它们。
- 接下来,对于每个预连接的域,验证是否向其发送了请求,并且请求在10秒内发生,以避免过早关闭连接。大多数瀑布图将允许您按域或部分URL进行过滤,如下所示。这使得查看请求是否以及何时发生在域中变得更加容易。
- 最后,查看每个资源提示并确保<link>标记中没有多个提示。