dns-prefetch需置于<head>最前,仅限协议+域名格式,只对确定使用的第三方域名启用,避免与preconnect混用,且不保证执行。

直接在 <head> 里加 <link rel="dns-prefetch"> 就能生效,但加错位置、写错格式或滥用域名反而拖慢首屏——关键不在“加不加”,而在“加给谁”和“怎么加”。
必须放在 <head> 里,且越靠前越好
浏览器解析 HTML 是流式进行的,<link rel="dns-prefetch"> 需要在首次遇到跨域资源前就被看到,否则可能来不及预解析。如果把它塞在 <body> 底部,或者被 JS 动态插入,基本等于没写。
- ✅ 正确位置:
<head>开始后、其他<link>(如 CSS)之前 - ❌ 错误做法:放在
<body>中、用document.write()注入、或依赖 JS 执行后才挂载 - ⚠️ 注意:它不阻塞渲染,但浏览器会优先调度空闲时执行,放太晚可能被首屏资源抢占带宽和 CPU
href 只能是协议+域名,不能带路径或端口
dns-prefetch 的本质是让系统缓存 DNS 查询结果,只关心“哪个域名”,不涉及具体资源路径或连接方式。写错格式会导致标签被忽略,且无任何报错提示。
- ✅ 合法写法:
<link rel="dns-prefetch" href="https://fonts.googleapis.com">、<link rel="dns-prefetch" href="//cdn.example.com"> - ❌ 非法写法:
href="https://cdn.example.com/js/app.js"(含路径)、href="cdn.example.com:8080"(显式端口)、href="http:/cdn.example.com"(协议拼错) - ⚠️ 协议相对写法
//cdn.example.com虽然可用,但在 HTTP/2+ 环境下建议显式写https://,避免某些旧版浏览器或中间设备误判协议
只对确定会用到的第三方域名开,别贪多
每个 dns-prefetch 都会触发一次独立 DNS 查询,浏览器虽有并发限制(通常 6~10 个),但无效查询既占带宽又耗系统资源,还可能干扰真实请求的优先级。
立即学习“前端免费学习笔记(深入)”;
- ✅ 推荐场景:字体服务(
fonts.googleapis.com)、统计上报(stats.example.com)、CDN 图片域(img.example-cdn.com)、登录态 API 域(auth.api.example.com) - ❌ 慎用场景:广告联盟(域名不稳定、可能被拦截)、未启用 HTTPS 的子域(存在降级风险)、用户点击后才加载的懒加载模块所用域名(可改用 JS 触发时再
new Image().src或fetch()触发解析) - ⚠️ 不支持通配符,
href="//*.example.com"无效;也别为同一主域写多个子域(如cdn1.example.com和cdn2.example.com),除非它们确实由不同权威 DNS 管理
别和 preconnect 混用,除非你明确需要建连
dns-prefetch 只做 DNS 解析,preconnect 会进一步完成 TCP 握手甚至 TLS 协商。后者开销更大,也更敏感——如果目标域名不支持 HTTP/2、证书即将过期或 CDN 节点不可达,preconnect 可能失败并占用连接池。
- ✅ 用
dns-prefetch:你只确定“后面大概率要访问这个域名”,比如用户点击按钮后加载第三方组件 - ✅ 用
preconnect:该域名承载首屏关键资源(如核心 JS/CSS),且你已确认其稳定性、协议兼容性与 TLS 配置 - ⚠️ 同时写两者无意义:浏览器遇到
preconnect会自动包含 DNS 解析,重复声明纯属冗余
真正容易被忽略的是:它不保证执行。浏览器可能因网络忙、内存紧张或策略判断(如低电量模式)跳过所有 dns-prefetch。所以它只是“尽力而为”的提示,不是硬性指令——别把它当性能兜底方案,而应配合资源加载时机、HTTP/2 多路复用和合理域名收敛一起用。



















