DNS Prefetch、Preload、Preconnect、Prerender完全指南:前端资源加载优化实战
做前端性能优化这些年,保哥发现很多开发者对浏览器提供的资源加载提示(Resource Hints)理解得比较模糊——dns-prefetch、preconnect、preload、prefetch、prerender,这几个长得像、功能各异的关键词,到底什么时候该用哪个?用错了会不会适得其反?
今天这篇文章,保哥就系统地把这几项技术从底层原理到实战场景全部拆解清楚,并且带你了解 2025 年 Chrome 主推的 Speculation Rules API 这个"大杀器"。读完你就知道怎么在项目中精准落地了。
一、为什么资源加载提示如此重要?
用户在浏览器地址栏输入一个域名后,背后会经历 DNS 解析 → TCP 握手 → TLS 协商 → 发送 HTTP 请求 → 接收响应 → 解析渲染 这一系列步骤。其中,光 DNS 解析这一步,延迟通常在 20~250 毫秒之间,如果 DNS 服务器负载较高,甚至可能更长。
对于页面中引用了大量第三方资源(Google Fonts、Analytics、CDN 上的 JS/CSS 文件、社交分享组件等)的网站来说,每多一个跨域请求,就多一次完整的连接建立过程。这些"看不见的等待"累加起来,直接拖慢了 First Contentful Paint(FCP)和 Largest Contentful Paint(LCP)等核心指标。
资源加载提示的本质,就是让浏览器在空闲时提前做好准备工作,把这些"隐形延迟"消灭在用户感知之前。
二、四大资源提示技术详解
2.1 DNS Prefetch——最轻量的"提前打招呼"
做什么:仅提前完成目标域名的 DNS 解析,将域名映射为 IP 地址,不做任何连接建立或资源下载。
语法:
<link rel="dns-prefetch" href="//cdn.example.com">特点:
- 开销极小,一次 DNS 查询消耗的带宽几乎可以忽略不计
- 浏览器兼容性最好,几乎所有主流浏览器都支持
- 只对跨域域名有效——你自己站点的域名在用户访问时早已解析完成,无需重复操作
最佳使用场景:
- 页面中引用的 Google Fonts、Google Analytics、CDN 域名等第三方服务
- 你确定页面上某些链接的域名需要解析,但不确定用户是否一定会点击
保哥实战建议:对于一个典型的企业官网或博客,在 <head> 中放 3~5 条 dns-prefetch 针对高频第三方域名是标准做法。不要贪多,十几条以上就失去意义了。
2.2 Preconnect——更进一步的"握手准备"
做什么:在 DNS 解析的基础上,还会完成 TCP 握手和 TLS 协商(如果是 HTTPS 的话)。等于提前把整个连接链路都建好了,只差最后发请求。
语法:
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>注意:如果目标资源会以匿名模式加载(如字体文件),务必加上 crossorigin 属性,否则浏览器只会做 DNS 查询,不会完成完整握手。特点:
- 比 dns-prefetch 多完成了 TCP + TLS 步骤,节省的时间更多(实测可节省 100~500ms)
- 开销比 dns-prefetch 大,浏览器有并发限制
- 如果建好的连接在 10 秒内未被使用(Chrome 的策略),连接会自动关闭,白白浪费了 CPU 和带宽
最佳使用场景:
- 你非常确定即将用到的关键第三方源,例如字体服务、核心 API 域名
- 页面加载路径中必经的跨域资源
保哥实战建议:preconnect 建议控制在 2~3 个域名以内。Google PageSpeed Insights 也会在超过 2 个 preconnect 时给出警告。一个成熟的做法是:关键域名用 preconnect,非关键域名用 dns-prefetch 做兜底。
两者组合使用的经典写法:
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="dns-prefetch" href="https://fonts.gstatic.com">这样一来,支持 preconnect 的浏览器走全连接,不支持的至少也能完成 DNS 解析,是一种优雅的降级策略。
2.3 Preload——"立刻给我下载这个资源"
做什么:强制浏览器以高优先级立即下载指定资源并缓存到本地,供当前页面使用。
语法:
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/css/critical.css" as="style">
<link rel="preload" href="/js/app.js" as="script">特点:
- 这不是"提示(hint)",而是命令(directive)——浏览器必须执行
as属性是必填的,它告诉浏览器资源类型(font/style/script/image 等),影响优先级排序和安全策略- 下载完成后资源缓存在内存中,不会自动执行或应用,需要页面中对应的标签来消费它
- 消耗带宽和网络资源较多
最佳使用场景:
- 关键字体文件(字体通常藏在 CSS 文件中,浏览器要先下载 CSS 再发现字体,preload 可以跳过这个等待)
- 首屏关键 CSS / JS 文件
- 首屏大图(Hero Image)
保哥实战建议:preload 的使用一定要克制。只 preload 首屏渲染必须的资源,不要把所有 JS/CSS 都加上 preload,否则会与真正需要的资源抢带宽,反而拖慢页面。保哥曾见过一个项目 preload 了 12 个资源,LCP 反而比不加还慢——因为真正的关键资源被挤到了后面。
2.4 Prefetch——"空闲时帮我囤点货"
做什么:以低优先级在浏览器空闲时下载资源,并缓存到浏览器中,供后续页面导航时使用。
语法:
<link rel="prefetch" href="/next-page.html">
<link rel="prefetch" href="/images/hero-next.jpg">特点:
- 低优先级——不会影响当前页面的加载
- 下载的资源缓存在 HTTP 缓存中,用户导航到目标页面时直接从缓存取
- 浏览器并不保证一定会执行——例如 Firefox 在网络慢或系统繁忙时会跳过 prefetch
- 适合为下一页提前备货
最佳使用场景:
- 电商网站中用户大概率点击的商品详情页资源
- 登录页面预取登录成功后要展示的页面资源(Netflix 用此策略将 Time to Interactive 降低了 30%)
- 博客文章列表页预取热门文章的 HTML
保哥实战建议:prefetch 是一种"赌注"——赌用户接下来会访问某个页面。赌对了,体验飞起;赌错了,白白浪费了带宽。所以一定要基于用户行为数据来决定 prefetch 哪些资源,而不是拍脑袋全站预取。
2.5 Prerender——"把下一页直接画出来"
做什么:在后台完整加载并渲染整个页面,包括所有子资源(HTML、CSS、JS、图片等),并执行 JavaScript。当用户真正导航时,几乎是瞬间呈现。
传统语法:
<link rel="prerender" href="https://example.com/next-page.html">特点:
- 效果最强悍——页面切换延迟可低至约 50 毫秒,肉眼几乎无法察觉
- 资源开销最大——相当于在后台打开了一个完整的标签页
- 风险也最大——预渲染的页面会执行所有 JS,可能触发统计计数、状态变更等副作用
- 如果用户没有访问预渲染的页面,所有开销都白费了
重要提醒:传统的 <link rel="prerender"> 在 Chrome 中已经被弃用,降级为了一种名为 NoState Prefetch 的行为(只预取资源,不做完整渲染)。真正的预渲染能力已经转移到了 Speculation Rules API,保哥下面会详细讲。
三、一张表看清所有区别
| 技术 | 操作范围 | 优先级 | 开销 | 适用场景 |
|---|---|---|---|---|
| dns-prefetch | 仅 DNS 解析 | 低 | 极小 | 第三方域名,不确定是否访问 |
| preconnect | DNS + TCP + TLS | 低 | 小 | 确定会用到的关键第三方源 |
| preload | 下载并缓存到内存 | 高(命令) | 中 | 当前页面关键资源 |
| prefetch | 下载并缓存到磁盘 | 低(提示) | 中 | 下一页面可能需要的资源 |
| prerender | 完整加载+渲染页面 | 低(提示) | 很大 | 几乎确定用户会访问的下一页 |
你可以使用保哥开发的页面渲染对比工具来直观对比优化前后的页面加载效果。
四、2025 年新利器:Speculation Rules API
如果你觉得上面那些 <link rel="..."> 的方式还不够强大和灵活,那 Chrome 团队在 2023 年推出并持续演进的 Speculation Rules API 绝对值得关注。这是目前最先进的预取/预渲染机制,也是保哥目前在新项目中重点采用的方案。
4.1 基本原理
Speculation Rules API 通过在页面中嵌入一段 JSON 配置来告诉浏览器:哪些页面应该被预取或预渲染。
<script type="speculationrules">
{
"prerender": [
{
"where": { "href_matches": "/articles/*" },
"eagerness": "moderate"
}
],
"prefetch": [
{
"urls": ["/about", "/contact"]
}
]
}
</script>4.2 核心优势
比传统方式强在哪里?
- 更精细的控制力:支持 URL 模式匹配、CSS 选择器匹配,可以用
where条件灵活指定目标 - eagerness 机制:提供四档策略——
immediate(立即执行)、eager(较积极)、moderate(鼠标悬停时触发)、conservative(点击时触发),让你在性能收益和资源开销之间找到最佳平衡点 - 浏览器智能决策:浏览器会综合考虑用户的网络状况、电池电量、系统负载等因素决定是否执行预加载。在慢速连接或低电量下,浏览器可能自动跳过预渲染
- 内存管理:Chrome 限制同时最多保持 2~10 个预渲染页面(取决于 eagerness 设置),采用先进先出策略自动回收旧的预渲染
- 缓存复用:即使预渲染被取消,已下载的子资源仍会保存在 HTTP 缓存中,后续导航还能受益
4.3 实战配置示例
博客/内容站——对所有文章链接启用 moderate 预渲染:
<script type="speculationrules">
{
"prerender": [
{
"where": { "and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/logout" } },
{ "not": { "href_matches": "/admin/*" } },
{ "not": { "selector_matches": ".no-prerender" } }
]},
"eagerness": "moderate"
}
]
}
</script>这段配置的意思是:预渲染站内所有链接,但排除登出页面、后台页面以及带 .no-prerender 类名的链接。eagerness 设为 moderate,意味着用户鼠标悬停在链接上时才触发。
电商站——分层策略:
<script type="speculationrules">
{
"prefetch": [
{
"where": { "href_matches": "/products/*" },
"eagerness": "moderate"
}
],
"prerender": [
{
"where": { "href_matches": "/cart" },
"eagerness": "conservative"
}
]
}
</script>商品页用 prefetch(开销小,覆盖面广),购物车页面用 prerender(用户意图明确时提供极速体验)。
4.4 最新进展:Prerender Until Script
2025 年底 Chrome 团队提出了一个新模式:prerender_until_script。它的工作方式是——预渲染页面时,遇到同步 <script> 标签就暂停,避免 JavaScript 执行带来的副作用(如触发统计、改变状态等)。
这意味着即使你的页面有复杂的 JS 逻辑,也可以安全地使用预渲染,因为页面的 HTML 结构和 CSS 样式会被提前渲染好,子资源也会被提前加载,只是 JS 执行被推迟到用户真正访问时。
<script type="speculationrules">
{
"prerender_until_script": [
{
"where": { "href_matches": "/*" },
"eagerness": "moderate"
}
]
}
</script>4.5 浏览器兼容性与降级
目前 Speculation Rules API 仅在 Chromium 内核浏览器(Chrome、Edge、Opera)中支持。但考虑到 Chrome 的全球市场份额超过 65%,以及这些浏览器加起来覆盖了绝大多数用户,投入产出比非常可观。
对于不支持的浏览器,这段 <script type="speculationrules"> 会被直接忽略,不会报错也不会影响页面正常工作。你可以结合传统的 <link rel="prefetch"> 作为降级方案。
4.6 调试方法
在 Chrome DevTools 中,打开 Application 面板 → Background services → Speculative loads,可以查看:
- 哪些 URL 被预取/预渲染了
- 当前状态(成功、失败、等待中)
- 失败原因(如返回了 404、非 2xx 状态码等)
- 页面是否是通过预渲染激活的
五、CDN 缓存 vs. 浏览器资源提示——别搞混了
保哥经常被问到:"我已经用了 CDN,还需要搞这些 prefetch 吗?"
答案是:它们解决的问题完全不同。
- CDN:在服务器侧工作,通过全球分布的边缘节点(PoP)将内容缓存到离用户最近的位置,缩短的是服务器响应时间
- 资源提示:在浏览器侧工作,通过提前执行 DNS/连接/下载等操作,缩短的是浏览器从"决定要这个资源"到"拿到这个资源"之间的等待时间
两者是互补关系,同时使用效果最佳。CDN 让资源"离用户更近",资源提示让浏览器"更早动手"。
六、保哥的实战优化清单
以下是保哥在项目中实际使用的资源加载提示配置模板,你可以根据自己的项目情况调整:
<head>
<!-- 1. 关键第三方域名:preconnect + dns-prefetch 组合 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.yoursite.com" crossorigin>
<link rel="dns-prefetch" href="https://cdn.yoursite.com">
<!-- 2. 非关键第三方域名:仅 dns-prefetch -->
<link rel="dns-prefetch" href="https://www.google-analytics.com">
<link rel="dns-prefetch" href="https://connect.facebook.net">
<!-- 3. 当前页面关键资源:preload -->
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/css/critical.css" as="style">
<!-- 4. 下一页面资源:Speculation Rules(推荐) -->
<script type="speculationrules">
{
"prefetch": [
{
"where": { "href_matches": "/*" },
"eagerness": "moderate"
}
]
}
</script>
</head>核心原则总结:
- preconnect 限 2~3 个:只给最关键的第三方源用
- dns-prefetch 可以稍多:5~8 个常用第三方域名
- preload 要极其克制:只 preload 首屏关键路径上的资源,通常不超过 3~4 个
- prefetch / prerender 要基于数据:分析用户行为路径,对高转化路径做预取
- Speculation Rules 优先:新项目首选 Speculation Rules API,传统方式做降级
七、常见坑与注意事项
1. preconnect 不加 crossorigin 导致字体加载无优化
字体文件以匿名模式加载,如果 preconnect 不加 crossorigin,浏览器只会做 DNS 解析,不会建立完整连接,等于降级成了 dns-prefetch。
2. preload 资源未被使用会触发控制台警告
Chrome 会在 3 秒内检查 preload 的资源是否被页面消费。如果没用到,DevTools 控制台会出现警告。长期未清理会影响 Lighthouse 评分。
3. prefetch 可能引发隐私问题
预取操作会向目标服务器发送请求,如果目标页面设置了追踪 Cookie,可能在用户未实际访问的情况下就被记录。跨站 prefetch 在 Speculation Rules API 中有严格限制——如果用户在目标站点已有 Cookie,则不会执行跨站预取。
4. 预渲染页面的状态同步问题
如果用户在预渲染发生后改变了某些状态(比如添加了购物车商品),预渲染的页面可能显示旧数据。可以使用 Broadcast Channel API 来同步状态,或者用 Clear-Site-Data 响应头来清除过期的预渲染缓存。
5. 不要对动态内容激进预渲染
秒杀页面、库存实时变化的商品页、实时座位选择页等高度动态的内容,不适合做预渲染。这类页面更适合使用 prefetch 配合客户端更新策略。
八、配合工具验证优化效果
在做完资源提示优化后,保哥建议使用以下方式验证效果:
- Chrome DevTools → Network 面板:观察资源加载时序,确认 preload/prefetch 的资源是否按预期加载
- Chrome DevTools → Application → Speculative loads:检查 Speculation Rules 的执行情况
- Lighthouse / PageSpeed Insights:查看是否还有 "Preconnect to required origins" 或 "Preload key requests" 的建议
- 使用页面渲染对比工具对比优化前后的渲染瀑布图差异
- 使用HTML转TXT纯文本工具提取页面的纯文本内容,分析
<head>中的资源提示标签是否正确配置
总结
资源加载提示是前端性能优化中投入产出比极高的一项技术。从最轻量的 dns-prefetch 到最激进的 prerender,每种技术都有其明确的适用场景和代价。2025 年以后,Speculation Rules API 无疑是最值得关注的新方向——它把预取和预渲染的能力提升到了一个新高度,同时提供了更精细的控制和更智能的资源管理。
保哥的建议是:不要孤立地使用某一种技术,而是根据资源的重要性、用户行为路径、网络环境等因素,组合使用不同层级的资源提示,构建一套完整的"分层预加载策略"。这才是真正专业的前端性能优化思路。
希望这篇文章对你有帮助。如果你在实践中遇到了什么问题,欢迎留言交流。