六维教程

preload prefetch preconnect dns-prefetch 区分对比

这四个属性是前端性能优化的“四大金刚”,很多开发者容易搞混。

底层逻辑

  • dns-prefetch:只做 DNS 域名解析(找门牌号)。
  • preconnect:做 DNS + TCP + TLS 完整握手(敲门+寒暄+加密通话),是 dns-prefetch 的升级版。
  • preload当前页面必须用的资源,现在立刻以最高优先级去下载(救急用)。
  • prefetch下一个页面可能用的资源,等浏览器闲着没事了再去低优先级下载(备胎用)。

区别对比

属性 做的事情 优先级 适用对象 浏览器处理时机
dns-prefetch DNS 查询 极低(轻量) 跨域第三方域名 立刻发起,但仅限 DNS
preconnect DNS + TCP + TLS 较高(占连接池) 极其重要的跨域域名 立刻发起完整握手
preload 下载完整文件 最高(Must Have) 当前页的关键静态资源 立刻以最高优先级下载
prefetch 下载完整文件 最低(Nice to Have) 下个页面的静态资源 浏览器空闲时下载(可能不下载)

实战举例

阻塞渲染

当前页阻塞渲染的 CSS / 字体 / 关键 JS(用 preload),例如:tailwind.cssstyle.css、首页首屏的 Hero 背景图、自定义字体。

这些资源不加载完,页面就白屏。浏览器默认按顺序解析 HTML,用 preload 强制浏览器提前下载,抢带宽。

<link rel="preload" href="/tailwind.css" as="style" />
<link rel="preload" href="/style.css" as="style" />
<link rel="preload" href="/fonts/essential.woff2" as="font" crossorigin />

重要跨域资源

当前页必须加载的跨域第三方(用 preconnect + dns-prefetch),例如:Google AdSense(你需要它赚钱)、Google Fonts、第三方登录 API(如 GitHub OAuth)。

跨域 HTTPS 涉及 TLS 握手(耗时长),必须提前握好手。加 dns-prefetch 是为了兼容 IE 等老旧浏览器。

<link rel="preconnect" href="https://pagead2.googlesyndication.com" />
<link rel="dns-prefetch" href="//pagead2.googlesyndication.com" />

次要跨域资源

当前页次要的跨域统计/分析(只用 dns-prefetch),例如:百度统计 hm.baidu.com、Google Analytics(非核心,丢了也不影响页面功能)。

不需要抢连接池资源(浏览器同域名最多 6 个并发),只做个 DNS 缓存,让统计代码不拖慢主流程就行。

<link rel="dns-prefetch" href="//hm.baidu.com" />

下一页资源

用户即将访问的下一页资源(用 prefetch),例如:列表页的第 2 页数据、详情页的评论区 JS、用户鼠标悬停在“下一篇”按钮上的目标页面。

当前页用不到,但用户大概率会点。浏览器会在主资源加载完、网络空闲时偷偷去下载。

prefetch 下载后存在缓存中,不一定成功(取决于带宽和 CPU),且不适合 POST 请求。

<!-- 鼠标悬停时触发加载下一页 -->
<link rel="prefetch" href="/page/2/index.html" />
<link rel="prefetch" href="/assets/next-page.js" />

注意事项

  1. 不要 preload 所有东西:浏览器带宽有限,preload 会挤占图片、其他 CSS 的下载。只给“首屏必须”的东西用。
  2. 不要给自己的主域名 dns-prefetch:用户已经在访问你的主域名了,DNS 早就缓存了,写了白写。
  3. 不要过度使用 preconnect:浏览器早期连接池有限(Chrome 最多 4-6 个),同时预连 10 个域名会导致连接竞争,反而变慢。只给最重要的 1-2 个第三方用。

最终结论

你的资源类型 用什么 示例代码
自己的 CSS / 字体 / LCP 图片 preload <link rel="preload" href="/style.css" as="style">
要赚钱的广告服务(Google) preconnect + dns-prefetch <link rel="preconnect" href="https://pagead2.googlesyndication.com">
统计/客服/非核心 SDK dns-prefetch <link rel="dns-prefetch" href="//hm.baidu.com">
用户下一个可能会点的页面 prefetch <link rel="prefetch" href="/next-page.html">
你的主站域名 啥都不用 浏览器自己会复用现有连接