预加载关键资源应使用link rel="preload",指定as属性以明确资源类型和优先级,配合font-display: swap解决字体阻塞,并通过JS动态插入处理运行时资源,且需在DevTools中验证请求时机与状态。

预加载关键资源用 link rel="preload"
浏览器默认只对 HTML 中的 、、 等标签做发现式加载,其他资源(比如字体、关键 JS 模块、首屏视频 poster)往往要等 DOM 解析到对应位置才开始请求,造成延迟。rel="preload" 是唯一能让浏览器「提前发起请求但不执行」的标准方式。
-
as属性必须指定,否则浏览器无法确定优先级和 CORS 行为(例如as="font"会触发crossorigin自动添加) - 只对当前页面真正需要的资源用,别盲目 preload 所有
.js或.css—— 它会抢占带宽,反而拖慢首屏渲染 - 不能替代
rel="prefetch":后者是低优先级、空闲时加载,用于下一页;preload是高优先级、立即加载,用于当前页
字体加载阻塞问题:用 font-display: swap 配合 preload
即使预加载了字体文件,如果 CSS 中没设置 font-display,浏览器仍会阻塞文本渲染直到字体加载完成(FOIT)。只加 preload 不解决渲染卡顿。
-
font-display: swap让浏览器先用备用字体渲染,字体就绪后无感替换 -
preload+swap组合才能实现「快速可见 + 最终美观」 - 避免在
@font-face中写url(...)同时又在外面preload同一地址 —— 可能触发重复请求(尤其在 Safari 中)
@font-face {
font-family: 'Inter';
src: url('/fonts/inter.woff2') format('woff2');
font-display: swap;
}
动态资源如何预加载?用 document.createElement('link') 手动插入
服务端无法预知某些运行时才确定的关键资源(比如根据用户设备加载不同分辨率图片、AB 实验用的 JS 脚本),这时得靠 JS 主动触发 preload。
- 必须在
document.head中 append,且最好在DOMContentLoaded前执行(越早越好) - 插入后浏览器立即开始请求,但不会自动执行或应用(例如 script 不会运行,font 不会生效),需后续手动处理
- 注意内存泄漏:不要反复创建相同
href的 preload link,可先查重
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'script';
link.href = '/js/feature-a.js';
document.head.appendChild(link);
Chrome DevTools 里怎么验证 preload 是否生效?
光写对标签没用,得确认浏览器真发出了请求、且优先级正确。打开 Chrome DevTools → Network 面板 → 刷新页面 → 筛选 Preload 列(右键表头开启)。
立即学习“前端免费学习笔记(深入)”;
- 看到资源状态为
200且Initiator是preload,说明生效 - 对比不加 preload 时的时间线:预加载资源的
Start Time应明显早于它在 HTML 中首次出现的位置 - 如果看到
cancelled或404,检查路径是否拼错、CORS 是否漏设(尤其字体)
最容易被忽略的是:preload 只影响「网络请求发起时机」,不控制执行顺序。JS 文件 preload 后仍需显式 或 eval() 才会运行 —— 这点很多人以为 preload 后就自动执行了。










