nginx 不执行 dns prefetch,仅通过 add_header 注入 link 响应头(如 link '; rel=dns-prefetch')或透传 html 中的 标签,由浏览器主动发起预解析;该机制与 resolver 指令无关,后者用于 nginx 自身反向代理时的动态域名解析。

在 Nginx 提供静态资源服务时,DNS 预解析(DNS Prefetch)本身并不由 Nginx 直接执行,而是通过向浏览器发送特定 HTTP 响应头或注入 HTML 标签,让客户端提前发起 DNS 查询。Nginx 的作用是正确透传、生成或注入这些预解析指令,从而提升页面首次加载中对 CDN、API 或第三方域名的访问速度。
明确 DNS Prefetch 的生效位置
DNS Prefetch 是前端优化手段,依赖浏览器行为,不是 Nginx 的内置解析功能。它有两种主流实现方式:
-
HTML 中声明:在网页
内添加<link rel="dns-prefetch" href="//cdn.example.com">,适用于已知固定域名的静态站点 -
HTTP 响应头注入:通过 Nginx 的
add_header指令,在返回 HTML 响应时附带 Link 头,例如:add_header Link '/cdn.example.com>; rel=dns-prefetch, /api.example.com>; rel=dns-prefetch';
注意:Link 头中的域名必须使用双斜杠协议相对写法(//xxx),且仅对同协议请求生效;不支持通配符或变量,需静态指定。
Nginx 配置 DNS Prefetch 的实操要点
若你用 Nginx 直接托管 HTML 文件(如单页应用或纯静态站),可在 server 或 location 块中添加响应头:
- 只对
text/html类型响应添加,避免污染 CSS/JS 等资源头:location ~ \.html$ { add_header Link "..."; } - 多个域名用英文逗号分隔,每个用单引号包裹,避免空格和特殊字符引发解析错误
- 不建议对所有响应统一加该头,否则可能触发无意义的 DNS 查询,增加客户端负担
- 若 HTML 已内联了
<link rel="dns-prefetch">,Nginx 无需重复添加,除非你希望覆盖或补充
别把 DNS Prefetch 和 resolver 混淆
这是常见误区:Nginx 的 resolver 指令用于自身动态解析(如 proxy_pass http://$host),与浏览器端的 DNS Prefetch 完全无关。
-
resolver是 Nginx 进程启动后用于反向代理、重定向等内部操作的 DNS 解析器,配置在http块顶层 - DNS Prefetch 是告诉浏览器“你接下来可能会访问这些域名,请现在就查一下”,不消耗 Nginx 资源
- 两者可共存,但目标不同:一个服务端用,一个客户端用;一个解决代理转发问题,一个缩短首屏 TTFB
配合其他 DNS 优化效果更佳
单独加 DNS Prefetch 收益有限,建议组合使用:
- 减少页面引用的独立域名数量(例如合并图片到同一 CDN 域名下),从源头降低 DNS 查询次数
- 确保关键域名的 DNS TTL 设置合理(建议 ≤ 300 秒),便于后端变更时快速生效
- 启用
preconnect(比 prefetch 更进一步):add_header Link '/cdn.example.com>; rel=preconnect; crossorigin';
它不仅查 DNS,还会提前建立 TCP 连接甚至 TLS 握手,适合高优先级资源 - 验证是否生效:在 Chrome DevTools 的 Network → Headers 标签中查看响应头 Link 字段,或在 Timing 标签中观察 DNS Lookup 阶段是否明显缩短











