HTML 的 preload、prefetch 和 preconnect 有什么区别
HTML 的 preload、prefetch、preconnect 三者的根本区别是:preconnect 只提前建立连接、不下载任何资源;preload 为当前页面以高优先级提前下载「马上要用」的资源;prefetch 为下一个页面在浏览器空闲时以最低优先级预下载「以后可能用」的资源。用错场景的代价很直接——preload 的资源 3 秒内没用上,Chrome 会在控制台报警并白白占用带宽。
preconnect、preload、prefetch 各自解决什么问题?
结论:preconnect 省的是「连接时间」,preload 省的是「资源发现时间」,prefetch 省的是「下一次导航的等待时间」。
- preconnect:
<link rel="preconnect" href="https://cdn.example.com" crossorigin>,提前完成 DNS 解析、TCP 三次握手和 TLS 协商。一个跨域请求的连接开销通常是:DNS 20~120ms + TCP 1 个 RTT + TLS 1~2 个 RTT,跨境 CDN 轻松超过 300ms,preconnect 把这部分提前到 HTML 解析阶段完成。 - preload:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>,强制浏览器立刻以该资源类型对应的高优先级发起请求。它解决的是「资源藏在 CSS 的@import、JS 动态插入的<link>、或字体在 CSS 里才被引用,浏览器发现得太晚」这个问题。 - prefetch:
<link rel="prefetch" href="/next-page.js" as="script">,浏览器在空闲时下载,优先级为 Lowest,结果存进 HTTP 缓存,供后续导航复用。SPA 里 webpack 的/* webpackPrefetch: true */魔改注释、路由懒加载的预取都是这个机制。
preload 怎么用?为什么字体必须加 crossorigin?
结论:preload 的 as 属性必填且必须与真实资源类型一致,字体请求因为走匿名 CORS 模式,即使同源也必须写 crossorigin。
as决定优先级和用途,写错(比如字体写成as="font"却漏了crossorigin,或 CSS 写成as="script")会导致同一资源被下载两次。- 字体文件必须加
crossorigin,因为 CSS 字体请求按规范使用匿名 CORS 模式,缺少该属性时预加载的连接和实际请求的连接凭据模式不同,浏览器会重新请求一遍,preload 完全失效。 type="font/woff2"这类 MIME 声明可以让不支持该格式的浏览器直接跳过预加载。- preload 只下载不执行:预加载的 script 不会被执行,只是提前放进缓存。
prefetch 和 preload 有什么区别?
结论:preload 服务于「当前导航、马上要用」,prefetch 服务于「下一次导航、可能要用」,两者的优先级和触发时机完全不同。
preload 在 HTML 解析到 link 标签时就发出请求,优先级跟 as 指定的资源类型一致(script/style 通常 High 及以上);prefetch 的优先级是 Lowest,只在浏览器判断网络空闲时才下载。Chrome 对 preload 有硬性提醒:资源在 load 事件后 3 秒内未被使用,控制台会输出「was preloaded using link preload but not used within a few seconds」的警告。所以 preload 只给首屏关键资源用,一般控制在 3~6 个;prefetch 数量可以更宽松,但别拿它预取几十个 chunk。
preconnect 和 dns-prefetch 有什么区别?
结论:dns-prefetch 只做 DNS 解析,preconnect 做完 DNS + TCP + TLS,后者收益更大但开销也更大,实战中两者通常成对写。
<link rel="dns-prefetch" href="https://cdn.example.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
dns-prefetch 兼容性更好(老浏览器也支持),成本极低;preconnect 会占用 socket 和 CPU,建议只对 3~6 个真正关键的跨域源使用,写多了反而会挤占带宽、增加耗电,甚至在 HTTPS 页面里暴露到未使用的域。另外,若后续请求是 CORS 请求(字体、带 crossorigin 的 fetch),preconnect 必须同样加 crossorigin,否则浏览器会另开一条连接。
实际项目里怎么选?
结论:按「是否跨域 → 是否当前页面要用 → 是否马上要用」三步决策即可。
跨域关键源先用 preconnect + dns-prefetch 打底;当前页面马上要用、浏览器又发现得晚的资源用 preload(首屏字体、关键 CSS、被 JS 动态插入的图片);下一个页面或下一个路由才用的资源交给 prefetch。三者不是互斥关系,一个页面可以同时写,但每一条都要能在 Network 面板里看到实际收益,否则删掉。
总结一下:preconnect 建连不下载,preload 高优先级抢当前页面的关键资源,prefetch 低优先级囤下一页面要用的资源;判断标准永远是「什么时候用、谁用、急不急」。
原文链接:https://www.gj0.com/thread-994.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。