Published on

Resource Hints (preload, prefetch 及连接预热)

现代浏览器提供了一套强大的资源提示 (Resource Hints) 机制,它允许开发者通过在 HTML <head> 中使用特定的 <link> 标签,向浏览器提供关于未来可能需要的资源或网络连接的“线索”。这使得浏览器能够前瞻性地执行从低成本的 DNS 查询到高成本的资源预下载等一系列优化操作,从而显著缩短关键资源的加载时间,提升用户感知的页面性能。

连接预热 (Connection Priming):降低网络握手延迟

这类提示旨在预先完成建立网络连接所需的部分或全部“握手”过程,为后续的资源请求铺平道路。

dns-prefetch: 轻量级的 DNS 预解析

  • 作用: 指示浏览器仅提前对一个域名进行 DNS 解析。这是一个开销极低的操作,浏览器会在空闲时将域名解析为 IP 地址并放入本地缓存。当未来真正需要从该域名请求资源时,DNS 查询这一步(可能耗时 20-120ms)就已经被消除。
  • 适用场景: 当页面引用了多个不同第三方域名的资源时,使用此方法批量预解析这些域名非常有效。
<link rel="dns-prefetch" href="https://www.google-analytics.com">
<link rel="dns-prefetch" href="https://fonts.gstatic.com">

preconnect: 预建立完整连接

  • 作用: preconnectdns-prefetch 更进一步。它会指示浏览器完成完整的连接建立过程,包括 DNS 解析TCP 握手TLS 握手
  • 机制: 这个操作的开销相对更高,因为它会实际地在用户设备和服务器之间建立一个连接套接字。当真正的请求发出时,可以直接复用这个已经“预热”好的连接,从而消除所有握手延迟。
  • 适用场景: 用于那些确定性高、对性能至关重要的域名,例如托管 LCP 图片的 CDN、提供核心数据的 API 服务器等。建议仅对少数(1-2个)最关键的域名使用,避免创建不必要的连接。
<link rel="preconnect" href="https://cdn.example.com" crossorigin>

资源预取 (Resource Fetching):优化内容加载时机

这类提示会指示浏览器下载完整的资源,但它们的目标、时机和优先级截然不同。

prefetch: 预拉取未来页面的非关键资源

  • 作用: prefetch 是一个低优先级的提示,告诉浏览器某个资源在用户未来的导航中(例如,用户很可能会点击进入的下一个页面)可能会用到。
  • 机制: 浏览器会在当前页面加载完成后,在自身空闲时,以最低的优先级在后台下载这个资源并存入 HTTP 缓存。它完全不会与当前页面的关键资源抢占带宽。
<link rel="prefetch" href="product-details.js" as="script">

preload: 预加载当前页面的关键资源

  • 作用: preload高优先级下载一个资源,因为它对于当前页面的首次渲染至关重要,但可能被浏览器的预加载扫描器发现得较晚(例如,深埋在 CSS 文件中的字体,或由 JavaScript 动态加载的 LCP 图片)。
  • 机制: preload 仅下载资源到内存中待命,不会自动执行或应用。脚本需要通过 <script> 标签执行,CSS 需要通过 <link rel="stylesheet"> 应用。它必须包含 as 属性来告知浏览器资源的类型,以便进行正确的优先级排序和安全检查。
<link rel="preload" as="image" href="/images/hero-image.webp">
<link rel="preload" as="font" href="/fonts/myfont.woff2" type="font/woff2" crossorigin>

总结与对比

rel 属性核心作用优先级目标页面关键用途
dns-prefetch仅 DNS 解析当前或未来减少多个第三方域名的 DNS 延迟
preconnectDNS + TCP + TLS当前或未来为即将到来的关键连接预热,消除握手延迟
preload下载完整资源当前页面提升 LCP、FCP,加载迟发现的关键资源
prefetch下载完整资源最低未来页面提升后续页面的加载速度,改善多页面应用体验