dns-prefetch 必须同时满足位置在head靠前、href为//domain.com格式、目标域名确被后续JS请求三个条件才生效,否则静默忽略且无提示。

dns-prefetch 不是“加了就生效”,而是必须满足三个硬条件:位置对、href 格式对、目标域名真被后续 JS 请求——缺一不可,否则浏览器静默忽略,控制台零提示。
href 必须写成 //domain.com,不能带协议或路径
浏览器只从 href 中提取主机名做 DNS 查询,其余内容全被丢弃。写错一点,整个标签就失效,且不报错。
- ✅ 正确:
<link rel="dns-prefetch" href="//cdn.example.com">(双斜杠协议相对,兼容性最好) - ✅ 可接受(HTTPS 页面更稳):
<link rel="dns-prefetch" href="https://fonts.googleapis.com"> - ❌ 错误:
<link rel="dns-prefetch" href="https://cdn.example.com/js/app.js">(含路径,整个标签被忽略) - ❌ 错误:
<link rel="dns-prefetch" href="http://api.example.com">(HTTPS 页面中 Safari 等可能跳过) - ❌ 错误:
<link rel="dns-prefetch" href="cdn.example.com">(缺//,被当成本地路径处理)
必须放在 <head> 靠前位置,早于所有外部资源
浏览器流式解析 HTML,<link rel="dns-prefetch"> 一读到就排队执行。放晚了,首屏 JS/CSS 请求早已发出,预解析完全来不及。
- ✅ 推荐顺序:
<meta charset>→<title>→<link rel="dns-prefetch">× N → 首个<link rel="stylesheet">或<script src> - ❌ 无效位置:塞在
<body>里、包在<template>中、用 JS 动态插入(如document.createElement('link')) - ⚠️ Safari 更保守:若前面堆了大量 CSS/JS,DNS 查询可能被抢占调度优先级,延迟到空闲时才执行
只对“首屏后立即请求”的第三方跨域域名有效
dns-prefetch 不加速首屏资源,只影响后续异步请求(如 fetch()、懒加载图片、字体 CSS 加载)。它不是“越多越好”,而是“越准越好”。
立即学习“前端免费学习笔记(深入)”;
- ✅ 值得加:
//api.example.com(DOM ready 后 100ms 内调用fetch("https://api.example.com/"))、//hm.baidu.com(统计 SDK 初始化必发) - ❌ 别加:
//your-site.com(同源,DNS 缓存已共享)、//admin.example.com(子域通常复用主域缓存)、//ad.doubleclick.net(不稳定、常被拦截) - ⚠️ 每个
dns-prefetch都是一次真实 DNS 查询,浏览器并发上限通常为 6~10 个;乱加会挤占真实请求的队列
别和 preconnect 混用同一域名
preconnect 会隐含 dns-prefetch 行为,并进一步建连 + TLS 握手。两者混用同一域名,后者直接覆盖前者,还多占一次队列。
- ✅ 如果确定要高频使用某 CDN 域名(如
//cdn.example.com),优先用:<link rel="preconnect" href="https://cdn.example.com" crossorigin> - ❌ 不要同时写:
<link rel="dns-prefetch" href="//cdn.example.com">和<link rel="preconnect" href="https://cdn.example.com"> - ⚠️ 注意协议降级风险:当前页是 HTTPS,但目标域名只支持 HTTPS,却写了
//api.example.com,可能因降级为 HTTP 导致失败——这种场景应改用preconnect并声明crossorigin
最易被忽略的是:它完全静默。写错格式不会报错,Network 面板也看不到记录,只能靠对比真实请求的 DNS 时间是否下降来验证效果。



















