乐闻世界logo
搜索文章和话题

什么是 DNS 预解析,如何实现 DNS 预解析

3月7日 12:08

DNS 预解析(DNS Prefetching)是一种性能优化技术,通过提前解析域名,减少用户访问时的延迟。浏览器和现代应用广泛使用此技术来提升用户体验。

为什么需要 DNS 预解析

传统 DNS 解析的延迟

shell
用户点击链接 浏览器发起 DNS 查询 DNS 解析完成(20-100ms) 建立 TCP 连接 开始加载页面

问题

  • DNS 查询增加页面加载延迟
  • 用户等待时间变长
  • 影响用户体验

DNS 预解析的优势

shell
页面加载时 后台预解析可能访问的域名 用户点击时 DNS 已解析,直接建立连接 页面加载更快

优势

  • 减少页面加载延迟
  • 提升用户体验
  • 隐藏 DNS 查询时间

DNS 预解析的实现方式

1. HTML 预解析标签

dns-prefetch

html
<!DOCTYPE html> <html> <head> <!-- 预解析 CDN 域名 --> <link rel="dns-prefetch" href="//cdn.example.com"> <!-- 预解析图片域名 --> <link rel="dns-prefetch" href="//img.example.com"> <!-- 预解析 API 域名 --> <link rel="dns-prefetch" href="//api.example.com"> </head> <body> <!-- 页面内容 --> </body> </html>

preconnect

html
<!DOCTYPE html> <html> <head> <!-- 预连接(包含 DNS 解析 + TCP 握手) --> <link rel="preconnect" href="//cdn.example.com"> <link rel="preconnect" href="//api.example.com"> </head> <body> <!-- 页面内容 --> </body> </html>

dns-prefetch vs preconnect

特性dns-prefetchpreconnect
功能仅 DNS 解析DNS + TCP + TLS
资源消耗
适用场景可能访问的资源确定访问的资源

2. 浏览器自动预解析

工作原理

浏览器在解析 HTML 时,自动发现页面中的链接和资源,提前解析这些域名。

html
<!-- 浏览器自动预解析这些域名 --> <a href="https://www.example.com">链接</a> <img src="https://img.example.com/image.jpg"> <script src="https://cdn.example.com/script.js">

浏览器支持

浏览器支持情况备注
Chrome✅ 支持自动预解析
Firefox✅ 支持自动预解析
Safari✅ 支持自动预解析
Edge✅ 支持自动预解析

3. HTTP 头部预解析

http
HTTP/1.1 200 OK Content-Type: text/html Link: <//cdn.example.com>; rel=dns-prefetch Link: <//api.example.com>; rel=preconnect

服务器配置

nginx
location / { add_header Link '<//cdn.example.com>; rel=dns-prefetch'; add_header Link '<//api.example.com>; rel=preconnect'; }

4. JavaScript 预解析

使用 Image Hack

javascript
// 创建隐藏的 Image 元素触发 DNS 解析 function prefetchDNS(hostname) { const img = new Image(); img.src = '//' + hostname + '/favicon.ico?' + Date.now(); } // 预解析多个域名 prefetchDNS('cdn.example.com'); prefetchDNS('api.example.com'); prefetchDNS('img.example.com');

使用 Fetch API

javascript
// 使用 Fetch API 触发 DNS 解析 async function prefetchDNS(hostname) { try { await fetch('//' + hostname, { mode: 'no-cors' }); } catch (e) { // 忽略错误,只触发 DNS 解析 } } prefetchDNS('cdn.example.com');

DNS 预解析的最佳实践

1. 预解析关键资源

html
<!-- 预解析 CDN --> <link rel="dns-prefetch" href="//cdn.example.com"> <!-- 预解析 API --> <link rel="dns-prefetch" href="//api.example.com"> <!-- 预解析静态资源 --> <link rel="dns-prefetch" href="//static.example.com">

2. 合理使用预解析

优先级排序

  1. 首屏资源:CSS、关键 JS
  2. CDN 域名:静态资源 CDN
  3. API 域名:数据接口
  4. 第三方服务:分析、广告等

3. 避免过度预解析

html
<!-- ❌ 过度预解析,浪费资源 --> <link rel="dns-prefetch" href="//a.example.com"> <link rel="dns-prefetch" href="//b.example.com"> <link rel="dns-prefetch" href="//c.example.com"> <!-- ... 100 个预解析 --> <!-- ✅ 合理预解析,只预解析关键域名 --> <link rel="dns-prefetch" href="//cdn.example.com"> <link rel="dns-prefetch" href="//api.example.com">

4. 结合其他优化

html
<!DOCTYPE html> <html> <head> <!-- DNS 预解析 --> <link rel="dns-prefetch" href="//cdn.example.com"> <!-- 预连接(DNS + TCP + TLS) --> <link rel="preconnect" href="//api.example.com"> <!-- 预加载资源 --> <link rel="preload" href="/styles.css" as="style"> <link rel="preload" href="/script.js" as="script"> </head> <body> <!-- 页面内容 --> </body> </html>

性能影响分析

DNS 预解析的性能提升

场景无预解析有预解析提升
首次访问100ms0ms100ms
二次访问0ms(缓存)0ms(缓存)0ms
跨域资源80ms10ms70ms

资源消耗

资源类型消耗说明
网络带宽仅 DNS 查询
DNS 服务器负载少量额外查询
浏览器内存缓存 DNS 结果

监控和测试

测试 DNS 预解析

javascript
// 测试 DNS 预解析效果 const start = performance.now(); fetch('https://cdn.example.com/test.js') .then(() => { const end = performance.now(); console.log(`DNS 解析时间: ${end - start}ms`); });

监控工具

  • Chrome DevTools:Network 面板查看 DNS 查询时间
  • WebPageTest:分析 DNS 预解析效果
  • Lighthouse:性能评分和建议

面试常见问题

Q: dns-prefetch 和 preconnect 有什么区别?

A:

  • dns-prefetch:仅触发 DNS 解析,资源消耗低
  • preconnect:触发 DNS 解析 + TCP 握手 + TLS 握手,资源消耗较高,但连接建立更快

Q: DNS 预解析会影响性能吗?

A:

  • 正面影响:减少页面加载延迟,提升用户体验
  • 负面影响:少量额外的 DNS 查询,增加 DNS 服务器负载
  • 结论:合理使用预解析,性能提升远大于额外开销

Q: 什么时候应该使用 DNS 预解析?

A:

  1. 首屏资源:CSS、关键 JS 的域名
  2. CDN 域名:静态资源的 CDN
  3. API 域名:数据接口域名
  4. 第三方服务:确定会使用的第三方服务

Q: 浏览器会自动预解析吗?

A:

  • 会。现代浏览器(Chrome、Firefox、Safari、Edge)会自动预解析页面中发现的域名
  • 但手动预解析可以更精确地控制预解析的时机和范围

总结

方面说明
核心作用提前解析域名,减少延迟
实现方式HTML 标签、浏览器自动、HTTP 头部、JavaScript
关键标签dns-prefetch、preconnect
最佳实践预解析关键资源,避免过度预解析
性能提升减少 50-100ms 的页面加载延迟
资源消耗低,少量 DNS 查询

标签:DNS