dns-prefetch、preconnect 和 preload 有什么区别?
简化版
dns-prefetch 只提前解析域名,preconnect 提前完成 DNS、TCP、TLS 连接,preload 提前下载当前页面马上需要的关键资源。它们解决的层次不同:域名解析、连接建立、资源获取;用错会浪费带宽和连接资源。
详细版
常见写法:
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="preload" href="/fonts/app.woff2" as="font" type="font/woff2" crossorigin>
dns-prefetch 成本低,适合可能会用到的第三方域名;preconnect 成本更高,适合首屏确定要访问的重要跨源;preload 应只给关键资源,否则会和真正重要的资源抢带宽。面试中要把它们和关键渲染路径、连接耗时联系起来。
完整版教学
一、浏览器拿到资源前要走几步
一个跨源 HTTPS 资源从开始到下载,通常经历:
DNS 解析 -> TCP 握手 -> TLS 握手 -> HTTP 请求 -> 响应下载
如果 DNS 40ms、TCP 60ms、TLS 80ms,真正请求资源前就可能花掉 180ms。预连接类优化就是把这些前置成本提前做掉,减少关键资源等待。
记忆钩子:
dns-prefetch备地址,preconnect先牵线,preload直接搬货。
二、dns-prefetch:只解析域名
<link rel="dns-prefetch" href="//analytics.example.com">
dns-prefetch 只告诉浏览器提前把域名解析成 IP。它成本较低,不会建立 TCP/TLS 连接,适合第三方统计、广告、图片域名等“可能较快会用到”的域名。
但它不能减少 TCP 和 TLS 时间。如果首屏一定要从某 CDN 下载字体或核心脚本,只做 DNS 预解析可能不够。
三、preconnect:提前建连接
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
preconnect 会提前进行 DNS、TCP、TLS。对首屏关键跨源资源很有用,例如字体 CDN、核心 API 域名、关键图片 CDN。
它的成本也更高:浏览器和服务端都要维护连接。如果你对 10 个第三方域名都 preconnect,但首屏只用到 2 个,就会浪费连接槽、CPU 和电量。
四、preload:提前下载资源
<link rel="preload" href="/hero.webp" as="image">
<link rel="preload" href="/app.css" as="style">
preload 是资源级优先级提示,表示“这个资源当前页面马上要用”。它会真正发起下载,所以必须谨慎。as 很重要,浏览器用它设置优先级、CSP 类型和缓存匹配。
如果预加载字体,还要带上正确跨域属性:
<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>
五、三者对比和选择
| 场景 | 推荐 |
|---|---|
| 可能访问第三方统计域名 | dns-prefetch |
| 首屏必用跨源字体 CDN | preconnect |
| 首屏 LCP 大图已知 URL | preload as=image |
| 后续页面可能用到的资源 | prefetch 更合适 |
注意 prefetch 和 preload 也不同:prefetch 面向未来导航或低优先级资源,preload 面向当前页面关键资源。面试常把这几个放一起考。
六、滥用的代价
假设页面 preconnect 8 个域名,每个连接前置成本 100ms,浏览器会并行处理但仍占用网络栈资源。用户如果在弱网手机上打开页面,过多预连接会和 CSS、JS、图片下载竞争。
同样,preload 过多会把不关键资源提升优先级。结果可能是字体、首屏 CSS、LCP 图片互相抢带宽,反而让首屏变慢。
七、常见误区与追问
- 误区:预加载越多越快。 预加载会占用带宽和连接资源,滥用会变慢。
- 误区:dns-prefetch 和 preconnect 一样。 前者只解析 DNS,后者还建立 TCP/TLS 连接。
- 误区:preload 可以用于未来页面资源。 当前页关键资源用 preload,未来页面更适合 prefetch。
- 追问:preload 为什么要写
as? 浏览器需要知道资源类型来设置优先级和复用缓存。 - 追问:字体 preload 为什么常加 crossorigin? 字体跨源缓存和请求模式需要匹配,否则可能重复下载。
- 追问:如何判断是否该加 preconnect? 看首屏是否确定访问该跨源且连接耗时影响关键路径。
八、加强记忆
资源提示按网络阶段记最稳:dns-prefetch 提前解析域名,preconnect 提前建好安全连接,preload 提前下载当前页关键资源。优化目标是缩短关键路径,不是把所有资源都提前;越靠后的提示成本越高,越要确认资源真的关键。