了解 rel=preconnect 和 rel=dns-prefetch 资源提示以及如何使用它们。
浏览器必须先建立连接,然后才能向服务器请求资源。建立安全连接需要完成以下三个步骤:
查找域名并将其解析为 IP 地址。
设置与服务器的连接。
为安全起见,请对连接进行加密。
在这些步骤中的每一个步骤中,浏览器都会向服务器发送一部分数据,然后服务器会发回响应。从起点到目的地再返回的这一行程称为往返。
单次往返可能需要很长时间,具体取决于网络状况。连接设置过程最多可能涉及三次往返,在未优化的情况下,可能更多。
提前处理好上述事宜将使应用运行速度明显加快。本文介绍了如何使用两个资源提示 <link rel=preconnect>
和 <link rel=dns-prefetch>
实现此目的。
尽早与 rel=preconnect
建立联系
新型浏览器会尽力预测网页需要哪些连接,但无法可靠地预测所有连接。好消息是,您可以给他们提供一些(资源 😉?)提示。
向 <link>
添加 rel=preconnect
会告知浏览器您的网页打算与另一个网域建立连接,以及您希望尽快启动该过程。由于在浏览器请求资源时设置流程已完成,因此资源的加载速度会更快。
资源提示之所以得名,是因为它们不是强制性说明。它们提供有关您希望发生的情况的信息,但最终由浏览器决定是否执行这些操作。设置和保持连接处于打开状态是一项繁重的工作,因此浏览器可能会根据情况选择忽略资源提示或部分执行这些提示。
只需向您的页面添加一个 <link>
标记,便可告知浏览器您的意图:
<link rel="preconnect" href="https://example.com">
通过尽早与重要的第三方来源建立连接,您可以将加载时间缩短 100-500 毫秒。这些数字看起来可能很小,但会影响用户对网页性能的感受。
rel=preconnect
的用例
知道从哪里提取资源,但不知道提取的资源是什么
由于依赖项版本受到控制,您有时会遇到这种情况:您知道您将从特定 CDN 请求资源,但不知道其确切的路径。
另一种常见情况是从图片 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
的支持略有不同,因此 dns-prefetch
可以作为不支持 preconnect
的浏览器的后备方案。
<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">
<link rel="preconnect dns-prefetch" href="http://example.com">
对 Largest Contentful Paint (LCP) 的影响
使用 dns-prefetch
和 preconnect
可让网站缩短连接到其他源所需的时间。最终目标是尽可能缩短从其他来源加载资源的时间。
就 Largest Contentful Paint (LCP) 而言,最好能立即发现资源,因为 LCP 候选项是用户体验的重要组成部分。为 LCP 资源设置 fetchpriority
值为 "high"
可以进一步改善这一点,因为这会向浏览器表明此资源对其的重要性,以便浏览器尽早提取该资源。
如果无法立即使 LCP 素材资源可被发现,preload
链接(fetchpriority
值也为 "high"
)仍可让浏览器尽快加载资源。
如果这两种方法都不可用(因为确切资源要到网页加载后期才能确定),您可以对跨源资源使用 preconnect
,以尽可能减少资源晚发现的影响。
此外,从带宽用量方面来看,preconnect
的费用低于 preload
,但仍存在风险。与过多的 preload
提示一样,过多的 preconnect
提示仍会消耗 TLS 证书的带宽。请注意不要预连接到太多源,因为这可能会导致带宽争用。
总结
如果您知道自己很快就会从第三方网域下载内容,但不知道该资源的确切网址,这两个资源提示有助于提高网页速度。例如,分发 JavaScript 库、图片或字体的 CDN。请注意限制,仅对最重要的资源使用 preconnect
,对其余资源使用 dns-prefetch
,并始终衡量实际影响。