dns-prefetch标签必须以//开头指定纯域名,位置需在meta和title后首个跨域资源前,仅对后续异步请求有效,验证需清缓存并检查Timing面板中DNS Lookup是否提前。

href必须是//开头的纯域名,否则整个标签静默失效
浏览器只从href中提取主机名做 DNS 查询,其余内容全丢弃,且不报任何错误。写错等于没写,但你根本查不到它失效了。
- ✅ 正确:
<link rel="dns-prefetch" href="//api.example.com"> - ✅ 可接受(HTTPS 页面更稳):
<link rel="dns-prefetch" href="https://api.example.com"> - ❌ 错误:
<link rel="dns-prefetch" href="https://api.example.com/v1/user">(含路径,整个标签被忽略) - ❌ 错误:
<link rel="dns-prefetch" href="http://api.example.com">(HTTPS 页面大概率跳过) - ❌ 错误:
<link rel="dns-prefetch" href="api.example.com">(缺协议标识,被当成本地路径)
特别注意:如果目标 API 只支持 HTTPS,而当前页是 HTTP,//api.example.com 会降级为 HTTP 请求并失败——此时应换用 <link rel="preconnect" href="https://api.example.com" crossorigin>。
必须放在最前面,晚于首个CSS/JS就基本没用
浏览器流式解析 HTML,<link rel="dns-prefetch"> 一读到就排队执行。如果它出现在第一个 <link rel="stylesheet"> 或 <script src="...> 之后,相关请求往往已经发出。
- ✅ 推荐位置:
<meta charset>和<title>之后、首个跨域资源标签之前 - ❌ 无效位置:塞在
<body>里、包裹在<template>中、或由 JS 动态插入(如document.createElement('link')) - ⚠️ 即使位置正确,若前面堆了大量阻塞资源,DNS 查询可能被调度延迟;Safari 更保守,常等到空闲或用户交互后才执行
只对后续真实发起的第三方接口请求有效
dns-prefetch 不加速首屏资源,只影响 JS 中 fetch()、XMLHttpRequest、懒加载组件等后续异步请求。它不保证执行,只“提示”浏览器提前查 IP。
立即学习“前端免费学习笔记(深入)”;
- ✅ 有效场景:页面初始化后调用
fetch("https://api.example.com/data"),且已声明<link rel="dns-prefetch" href="//api.example.com"> - ❌ 无效场景:加了
//backup.api.com,但 JS 里根本没发请求;或同源接口(如/api/user)也加了,纯属浪费 - ⚠️ 每个预解析占用浏览器 DNS 并发队列(通常限 6~10 个),乱加会挤占真实请求的槽位
验证是否真起作用,别看首屏时间
收益只在「首次访问该域名且无缓存」时明显。缓存命中时 Timing 面板显示 DNS 时间为 0 是正常现象,不是优化失效。
- ✅ 正确验证方式:Chrome DevTools → Network → 找到目标接口请求 → 切换到「Timing」标签页 → 确认「DNS Lookup」阶段是否出现在
Start render之前,且耗时明显低于未加时基线值 - ✅ 必须清空缓存:
chrome://net-internals/#dns→ 点「Clear host cache」 - ✅ 禁用 uBlock Origin 等广告拦截扩展,它们会主动屏蔽
dns-prefetch请求 - ⚠️ 别对比「加了 vs 没加」的平均首屏时间——JS 执行、渲染阻塞等噪声会淹没真实收益
真正影响效果的从来不是“加没加”,而是“加得准不准、放得早不早、用得上不上”。它不报错、不警告、也不留日志,唯一证据藏在 Timing 面板里。



















