应在页面关键资源(如首屏字体、核心CSS/JS、hero图)被浏览器发现过晚导致渲染阻塞或FOIT/FOUT时使用<link rel="preload">,需严格匹配as属性、避免误用、区分prefetch/preconnect,并优先通过Chrome DevTools验证。

什么时候该用 <link rel="preload">
当页面关键资源(比如首屏字体、核心 CSS、JS 或 hero 图片)被浏览器发现得太晚,导致渲染阻塞或 FOIT/FOUT 时,才值得手动预加载。不是所有资源都适合——preload 会强制提前发起请求,但不执行,也不改变资源优先级逻辑;用错反而挤占带宽、干扰正常加载顺序。
常见误用场景:
• 把整站 JS 都 preload(实际应靠 modulepreload 或 code-splitting)
• 对异步加载的图片或懒加载组件资源加 preload(违背“关键”原则)
• 在非首屏 HTML 中写 preload(可能被 Chrome 忽略,尤其动态插入的)
as 属性必须填对,否则降级为 fetch
浏览器靠 as 判断资源类型,从而匹配正确的请求头(如 Accept: font/woff2)、CSP 策略和缓存行为。填错就失去预加载意义,甚至触发跨域错误。
典型配对:
-
<link rel="preload" href="main.css" as="style">→ 触发text/css请求头 -
<link rel="preload" href="logo.svg" as="image">→ 支持Sec-Fetch-Dest: image -
<link rel="preload" href="icon.woff2" as="font" type="font/woff2" crossorigin>→ 字体必须带crossorigin,否则可能被拒绝 -
<link rel="preload" href="app.js" as="script">→ 不等于执行,只是提前下载;后续仍需<script src>引入
和 prefetch、preconnect 别混用
preload 是「我马上就要用这个资源」,而 prefetch 是「我之后可能会用」,浏览器对其优先级、缓存策略、触发时机完全不同。
容易踩的坑:
- 把第三方 API 域名写成
preload(应该用preconnect):<link rel="preload" href="https://api.example.com/data.json">❌ —— 这会尝试下载整个响应体,浪费流量 - 用
prefetch替代preload加载首屏字体(延迟明显,且可能不进内存缓存) - 同时写
preconnect和preload到同一域名:先preconnect再preload,否则连接可能未建立完就发请求,白忙活
HTTP 头也能写 Link: <...>; rel=preload
服务端推送已淘汰,但 HTTP 响应头里的 Link 仍是合法且有效的预加载方式,特别适合 SSR 场景或 CDN 配置。
示例(Nginx 配置片段):
add_header Link "</static/main.css>; rel=preload; as=style"; add_header Link "</static/icon.woff2>; rel=preload; as=font; crossorigin";
注意:
• 多个用英文逗号分隔
• 路径必须是绝对路径(以 / 开头)或完整 URL
• crossorigin 不能省,字体类资源否则 404
• 某些老旧 CDN(如早期 Cloudflare)可能 strip 掉 Link 头,上线前务必 curl 验证
真正难的不是怎么写这行标签,而是判断「它是不是当前页面最关键的那一个资源」——多一个 preload 不一定快,少一个也不一定慢。Chrome DevTools 的 **Waterfall** 和 **Coverage** 面板比任何文档都更清楚告诉你该 preload 谁。

















