DNS 预解析与资源预加载

dns-prefetch、preload、prefetch 的区别与使用场景

问题

解释 DNS 预解析 (dns-prefetch) 与 Preload/Prefetch 的区别和使用场景。

解答

dns-prefetch

提前解析域名的 DNS,减少后续请求的 DNS 查询时间。

<!-- 预解析第三方域名 -->
<link rel="dns-prefetch" href="https://cdn.example.com">
<link rel="dns-prefetch" href="https://api.example.com">
<link rel="dns-prefetch" href="https://fonts.googleapis.com">

preconnect

比 dns-prefetch 更进一步,除了 DNS 解析,还会建立 TCP 连接和 TLS 握手。

<!-- 预连接,适合确定会用到的域名 -->
<link rel="preconnect" href="https://cdn.example.com">

<!-- 跨域资源需要加 crossorigin -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

preload

预加载当前页面必需的资源,优先级高。

<!-- 预加载关键 CSS -->
<link rel="preload" href="/css/critical.css" as="style">

<!-- 预加载字体 -->
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>

<!-- 预加载首屏图片 -->
<link rel="preload" href="/images/hero.webp" as="image">

<!-- 预加载关键脚本 -->
<link rel="preload" href="/js/main.js" as="script">

as 属性值:

资源类型
styleCSS 文件
scriptJavaScript 文件
font字体文件
image图片
fetchfetch/XHR 请求

prefetch

预加载未来可能需要的资源,优先级低,浏览器空闲时加载。

<!-- 预取下一页资源 -->
<link rel="prefetch" href="/page2.html">
<link rel="prefetch" href="/js/page2.js" as="script">

<!-- 预取可能点击的图片 -->
<link rel="prefetch" href="/images/product-detail.jpg" as="image">

实际应用示例

<!DOCTYPE html>
<html>
<head>
  <!-- 1. DNS 预解析:第三方域名 -->
  <link rel="dns-prefetch" href="https://cdn.bootcdn.net">
  
  <!-- 2. 预连接:确定要用的 CDN -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  
  <!-- 3. 预加载:当前页面关键资源 -->
  <link rel="preload" href="/css/app.css" as="style">
  <link rel="preload" href="/js/app.js" as="script">
  <link rel="preload" href="/fonts/icon.woff2" as="font" type="font/woff2" crossorigin>
  
  <!-- 4. 预取:下一页可能用到的资源 -->
  <link rel="prefetch" href="/js/dashboard.js" as="script">
  
  <!-- 正常加载 CSS -->
  <link rel="stylesheet" href="/css/app.css">
</head>
<body>
  <!-- 页面内容 -->
  <script src="/js/app.js"></script>
</body>
</html>

JavaScript 动态添加

// 动态预加载
function preloadResource(url, as) {
  const link = document.createElement('link');
  link.rel = 'preload';
  link.href = url;
  link.as = as;
  document.head.appendChild(link);
}

// 路由切换前预取下一页资源
function prefetchNextPage(url) {
  const link = document.createElement('link');
  link.rel = 'prefetch';
  link.href = url;
  document.head.appendChild(link);
}

// 使用示例
preloadResource('/images/banner.jpg', 'image');
prefetchNextPage('/about.html');

对比总结

特性dns-prefetchpreconnectpreloadprefetch
作用DNS 解析DNS + TCP + TLS加载资源加载资源
优先级最低
使用场景第三方域名确定要用的域名当前页面关键资源未来可能用的资源
缓存

关键点

  • dns-prefetch 只做 DNS 解析,preconnect 还会建立连接
  • preload 用于当前页面必需资源,优先级高,必须指定 as 属性
  • prefetch 用于未来可能需要的资源,浏览器空闲时加载
  • 字体文件需要加 crossorigin 属性,即使同源
  • 过度使用会浪费带宽,只预加载真正需要的资源