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 属性值:
| 值 | 资源类型 |
|---|---|
| style | CSS 文件 |
| script | JavaScript 文件 |
| font | 字体文件 |
| image | 图片 |
| fetch | fetch/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-prefetch | preconnect | preload | prefetch |
|---|---|---|---|---|
| 作用 | DNS 解析 | DNS + TCP + TLS | 加载资源 | 加载资源 |
| 优先级 | 低 | 中 | 高 | 最低 |
| 使用场景 | 第三方域名 | 确定要用的域名 | 当前页面关键资源 | 未来可能用的资源 |
| 缓存 | 无 | 无 | 是 | 是 |
关键点
dns-prefetch只做 DNS 解析,preconnect还会建立连接preload用于当前页面必需资源,优先级高,必须指定as属性prefetch用于未来可能需要的资源,浏览器空闲时加载- 字体文件需要加
crossorigin属性,即使同源 - 过度使用会浪费带宽,只预加载真正需要的资源
目录