尽早建立网络连接,以提升系统感知的网页速度

了解 rel=preconnect 和 rel=dns-prefetch 资源提示以及如何使用它们。

浏览器必须先建立连接,然后才能从服务器请求资源。建立安全连接包括以下三个步骤:

  • 查找域名并将其解析为 IP 地址。

  • 设置与服务器的连接。

  • 加密连接以确保安全。

在每一个步骤中,浏览器都会向服务器发送一段数据,然后服务器会发回响应。从出发地到目的地再往回的这一旅程称为“往返”。

单次往返可能会花费大量时间,具体取决于网络状况。连接设置流程最多可能涉及三次往返,如未优化,则往返次数会更多。

提前处理好所有这些操作,可以提升应用的运行速度。这篇博文介绍了如何使用 <link rel=preconnect><link rel=dns-prefetch> 这两个资源提示来实现此目的。

尽早与rel=preconnect建立联系

现代浏览器会尽力预测网页需要哪些连接,但无法准确地预测所有连接。好消息是,你可以给他们一个(资源 画质)提示。

rel=preconnect 添加到 <link> 会通知浏览器您的网页打算与另一网域建立连接,并希望该过程尽快开始。资源加载速度会更快,因为在浏览器请求这些资源时,设置流程就已经完成了。

资源提示会获得它们的名称,因为它们不是强制性的说明。它们可提供有关您希望执行什么操作的信息,但是否执行这些任务最终由浏览器决定。设置并保持连接需要完成大量工作,因此浏览器可能会根据具体情况选择忽略资源提示或部分执行资源提示。

只需向您的网页添加 <link> 标记,即可告知浏览器您的意图:

<link rel="preconnect" href="https://example.com">

展示如何在建立连接后的一段时间内未开始下载的图片。

通过尽早与重要的第三方源建立连接,您可以将加载时间缩短 100-500 毫秒。这些数字可能看起来很小,但实际上会影响用户对网页性能的看法

rel=preconnect”的使用场景

知道出发地,但不了解要提取的内容

由于依赖项有版本控制,有时您有时会知道您将从特定 CDN 请求资源,但不知道其确切路径。

包含版本名称的脚本的网址。
带版本号的网址示例。

另一种常见情况是从图片 CDN 加载图片,其中图片的确切路径取决于用户浏览器的媒体查询或运行时功能检查。

图片 CDN 网址,参数为 size=300x400 且 quality=auto。
图片 CDN 网址示例。

在这些情况下,如果您要提取的资源非常重要,那么您希望通过预先连接到服务器来尽可能节省时间。在网页请求之前,浏览器不会下载文件,但至少它可以提前处理连接问题,让用户不必等待几次往返。

流媒体

另一个您想在连接阶段节省一些时间,但不一定立即开始检索内容的示例是在流式传输不同来源的媒体时。

根据您的网页处理流式传输内容的方式,您可能需要等待脚本加载完毕并准备好处理流式传输。在您准备好开始提取信息后,预连接功能可帮助您将等待时间缩短为单次往返时间。

如何实现 rel=preconnect

启动 preconnect 的一种方法是向文档的 <head> 添加 <link> 标记。

<head>
    <link rel="preconnect" href="https://example.com">
</head>

预连接仅对除源网域之外的网域有效,因此您不应该对您的网站使用预连接。

您还可以通过 Link HTTP 标头启动预连接:

Link: <https://example.com/>; rel=preconnect

某些类型的资源(例如字体)以匿名模式加载。对于后者,您必须使用 preconnect 提示设置 crossorigin 属性:

<link rel="preconnect" href="https://example.com/ComicSans" crossorigin>

如果您省略 crossorigin 属性,浏览器只会执行 DNS 查找。

通过 rel=dns-prefetch 尽早解析域名

您只需按名称记住网站,而服务器按 IP 地址记住网站。这就是域名系统 (DNS) 存在的原因。浏览器使用 DNS 将网站名称转换为 IP 地址。此过程(域名解析)是建立连接的第一步。

如果网页需要与许多第三方网域相关联,那么预先连接所有这些网域会适得其反。preconnect 提示最适合仅用于最关键的连接。对于其余所有操作,请使用 <link rel=dns-prefetch> 以节省在第一步(DNS 查找)上花费的时间,这通常需要 20-120 毫秒左右。

DNS 解析的启动方式与 preconnect 类似:通过向文档的 <head> 添加 <link> 标记来启动。

<link rel="dns-prefetch" href="http://example.com">

浏览器对 dns-prefetch 的支持与对 preconnect 支持略有不同,因此,对于不支持 preconnect 的浏览器,dns-prefetch 可作为后备方案。

正确做法
<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">
为了安全地实现后备广告技术,请使用单独的链接标记。
错误做法
<link rel="preconnect dns-prefetch" href="http://example.com">
在同一 <link> 标记中实现 dns-prefetch 回退会导致 Safari 中出现 bug,其中 preconnect 会被取消。

对 Largest Contentful Paint (LCP) 的影响

使用 dns-prefetchpreconnect 可让网站缩短连接到其他源站所需的时间。最终目标是应尽可能缩短从另一个来源加载资源的时间。

Largest Contentful Paint (LCP) 而言,资源最好能立即被发现,因为 LCP 候选项是用户体验的关键部分。LCP 资源上的 fetchpriority"high" 可以向浏览器表明此资源的重要性,以便它尽早提取它,从而进一步改善此问题。

如果 LCP 资源无法立即被发现,preload 链接(fetchpriority 值为 "high")仍会允许浏览器尽快加载资源。

如果这两个选项都不可用(因为确切的资源在网页加载后期才会知道),您可以对跨源资源使用 preconnect,以尽可能降低延迟发现资源的影响。

此外,就带宽使用量而言,preconnectpreload 便宜,但仍然没有风险。与 preload 提示过多的情况一样,对于 TLS 证书,过多的 preconnect 提示仍会占用带宽。注意不要预先连接过多源,因为这可能会导致带宽争用。

总结

如果您知道自己很快就会从第三方网域下载某项内容,但不知道相应资源的确切网址,那么这两个资源提示对于提升网页速度会很有帮助。例如,分发 JavaScript 库、图片或字体的 CDN。请注意约束条件,仅对最重要的资源使用 preconnect,其余资源依赖 dns-prefetch,并始终衡量对现实世界的影响。