dns-prefetch生效需同时满足href格式正确(仅协议相对主机名如//cdn.example.com)、置于head靠前位置(meta charset和title后、首个外链资源前)、目标域名确在首屏后JS中立即请求,缺一不可,否则静默失效。

link 标签做 DNS 预解析(dns-prefetch)只有在三个条件全部满足时才真正生效:href 格式正确、位置靠前、目标域名确实在首屏后立即被 JS 请求——缺一不可,否则浏览器静默忽略,连控制台警告都没有。
href 必须只写协议相对主机名,路径或协议头都会让整条标签失效
浏览器只从 href 属性中提取主机名,其余内容全被丢弃。写错不是“效果差”,而是“完全不执行”。
-
//cdn.example.com✅ 安全通用,适配当前页协议(HTTP/HTTPS) -
https://fonts.googleapis.com✅ HTTPS 页面可用,但 HTTP 页面会失败 -
//cdn.example.com/js/app.js❌ 含路径,整条<link rel="dns-prefetch">被忽略 -
https://cdn.example.com❌ Safari 15.4+ 可能跳过,旧版更不稳定 -
cdn.example.com❌ 缺//,被当成本地相对路径,查的是https://your-site.com/cdn.example.com
必须放在 和 之后、首个外链资源之前
浏览器是流式解析 HTML 的,dns-prefetch 标签被读到就立刻排队执行 DNS 查询。放晚了,首屏资源请求早就发出去了。
- ✅ 正确顺序:
<meta charset>→<title></title>→<link rel="dns-prefetch" href="//api.example.com">→<link rel="stylesheet" href="main.css"> - ❌ 塞在
里:规范不保证解析,多数浏览器直接跳过 - ❌ 用 JS 动态插入:
document.head.appendChild(link)太晚,失去预解析意义 - ⚠️ 即使位置正确,若顶部堆了大量阻塞渲染的 CSS/JS,DNS 查询也可能被调度延迟(Safari 尤其保守)
只对首屏后 JS 主动发起的跨域请求有效,同源或备用域名加了也白费
dns-prefetch 不加速 <img src alt="HTML页面如何使用link标签进行预解析优化" >、<script src></script> 这类同步资源,只影响后续 JS 中 fetch()、懒加载图片、字体 CSS 加载后的 @font-face 请求等。
立即学习“前端免费学习笔记(深入)”;
- ✅ 值得加:
//api.example.com(首页卡片数据 fetch)、//hm.baidu.com(统计 SDK 初始化必发) - ❌ 不该加:
//your-site.com(同源,DNS 缓存已共享)、//ad.doubleclick.net(不稳定、常被拦截) - ❌ 别加备用域名:
//backup-api.example.com(99% 不触发,还挤占浏览器 6–10 个并发 DNS 队列) - ⚠️ 如果目标域名只支持 HTTPS,但当前页是 HTTP,
//写法会降级为 HTTP 导致后续请求失败——这种场景应改用preconnect并显式声明crossorigin
别和 preconnect 混用同一域名,后者会覆盖前者
preconnect 已隐含 dns-prefetch 功能,还会进一步建连 + TLS 握手。两者同时写,preconnect 生效,dns-prefetch 白加。
- ✅ 确定 1–2 秒内必用的跨域资源(如字体、首屏 API)→ 用
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> - ✅ 只是“可能用到”或用户交互后才发请求(如分享按钮调用微博接口)→ 用
<link rel="dns-prefetch" href="//weibo.com"> - ❌ 同一域名同时写两者:
<link rel="dns-prefetch" href="//api.example.com">+<link rel="preconnect" href="//api.example.com">→ 后者覆盖前者,前者无效 - ⚠️
preconnect开销更大,浏览器并发连接数通常限 4–6 个,多连反而抢走主站资源
最容易被忽略的一点:预解析是否生效,不能靠代码写了就信。Chrome DevTools → Network 面板 → 筛选 Other 类型 → 找目标域名的真实请求(如 api.example.com/v1/data)→ 看 domainLookupStart 到 domainLookupEnd 是否接近 0ms;更直接的方法是访问 chrome://net-internals/#dns 刷新后搜索目标域名,看是否有缓存命中记录。



















