正确写法是href必须以//开头且仅含域名,如//cdn.example.com;需置于最前;只预解析确定会用的跨域第三方域名;勿与preconnect混用同一域名。

href 必须用 // 开头,不能带协议或路径
浏览器只从 href 中提取主机名做 DNS 查询,其余部分全被忽略。写错格式标签就等于没写,而且不会报错,很难排查。
常见错误包括:
-
<link rel="dns-prefetch" href="https://cdn.example.com">—— 显式https://在部分旧版 Safari 中会被跳过 -
<link rel="dns-prefetch" href="//cdn.example.com/js/app.js">—— 含路径,整个标签被浏览器静默忽略 -
<link rel="dns-prefetch" href="cdn.example.com">—— 缺少协议标识,被当成本地相对路径处理
✅ 正确写法只有两种:<link rel="dns-prefetch" href="//cdn.example.com">(推荐)或 <link rel="dns-prefetch" href="https://fonts.googleapis.com">(HTTPS 页面更稳)。
必须放在 最前面,早于所有外部资源
浏览器是流式解析 HTML 的,<link rel="dns-prefetch"> 一旦被读到就会立即排队执行。如果放晚了,相关资源请求早就发出去了,预解析就白做了。
立即学习“前端免费学习笔记(深入)”;
理想位置顺序是:
<meta charset><title></title>-
<link rel="dns-prefetch">× N -
<link rel="stylesheet">或首个<script></script>
❌ 错误做法:丢在 里、塞在 <template></template> 中、或用 JS 动态插入(如 document.createElement('link'))—— 这些都不会触发预解析。
只加确定会用的第三方域名,别碰同源和备用域名
dns-prefetch 每个都是一次真实 DNS 查询,浏览器并发上限通常为 6~10 个。无效查询不仅浪费系统资源,还可能挤占真实请求的调度优先级。
✅ 值得加的域名(满足“确定会用 + 跨域 + 非同源”):
-
//cdn.example.com(首屏图片/JS/CSS 真实加载自该 CDN) -
//api.example.com(首屏后立即fetch()的接口) -
//fonts.googleapis.com(页面中明确@import或<link rel="stylesheet">引入) -
//hm.baidu.com(统计 SDK 初始化时必然上报)
❌ 不该加的:
-
//example.com(主站域名,DNS 已缓存,冗余) -
//ad.doubleclick.net(广告联盟不稳定,常被拦截或延迟加载) -
//backup-cdn.example.com(备用 CDN,实际未启用) -
//service.qq.com(仅「联系我们」按钮跳转用,更适合用rel="prefetch"或 hover 时 JS 触发)
别和 preconnect 混用同一域名
preconnect 会隐含完成 DNS 解析 + TCP 连接 + TLS 握手(HTTPS),开销远高于 dns-prefetch。两者同时声明,浏览器会直接忽略 dns-prefetch,纯属冗余。
选哪个,看使用场景:
- 确定几秒内必发 HTTPS 请求(如首屏关键字体、API)→ 用
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> - 只是“可能用到”或“用户操作后才触发”(如分享按钮、埋点上报、懒加载脚本)→ 用
dns-prefetch更稳妥 - 目标域名只支持 HTTPS,但当前页是 HTTP →
//写法会降级为 HTTP 导致失败,此时必须改用preconnect并显式声明crossorigin
真正容易被忽略的是:Safari 对 dns-prefetch 执行更保守,常延迟到页面空闲甚至用户交互后才发起;且 DNS 缓存默认仅 60–300 秒,长停留后再点击,很可能又要重查。



















