预加载关键图片更可靠、更早触发且不阻塞渲染,但必须写as="image"和fetchpriority="high",否则浏览器降级为低优先级甚至忽略;其优势在于html解析早期即发起高优请求,而js创建image对象受执行时机、主线程阻塞和优先级缺失限制。

直接说结论:用 <link rel="preload"> 预加载关键图片,比用 JS 创建 Image 对象更可靠、更早触发、且不阻塞渲染;但必须配合 as="image" 和正确的 fetchpriority,否则浏览器可能忽略或降级优先级。
为什么 <link rel="preload"> 是首选方案
浏览器在解析 HTML 时,遇到 <link rel="preload"> 就会立即发起高优先级请求,远早于 JS 执行或 <img> 标签被解析。而 JS 创建 new Image() 要等 JS 执行完、DOM 构建完成,甚至可能被主线程阻塞——尤其在低端设备或长任务场景下,延迟可达数百毫秒。
常见错误是漏写 as="image":没有它,浏览器无法识别资源类型,会按默认低优先级处理,等同于白写。
-
<link rel="preload" href="hero.jpg" as="image">✅ 正确触发高优先级加载 -
<link rel="preload" href="hero.jpg">❌ 缺少as,降为低优先级,几乎无效 -
<link rel="prefetch" href="hero.jpg" as="image">❌prefetch是空闲时才加载,不解决首屏卡顿
loading="eager" 和 fetchpriority="high" 的实际作用
对于首屏关键图(如 banner、主视觉),不能只靠 loading="lazy" 的反向逻辑。必须显式提权:
-
loading="eager"强制取消懒加载行为,确保该<img>在 HTML 解析阶段就被发现 -
fetchpriority="high"是 Chrome 109+ 支持的明确优先级提示,对<img>和<link rel="preload">都有效,能覆盖浏览器默认的“图片低优先级”策略 - 两者要一起用:
<img src="hero.jpg" loading="eager" fetchpriority="high">
注意:fetchpriority 在 Safari 和旧版 Firefox 中被忽略,所以 <link rel="preload"> 仍是跨浏览器兜底关键。
预加载路径和尺寸匹配容易被忽略的坑
预加载的 URL 必须和最终 <img src> 完全一致(含查询参数、大小写、路径斜杠),否则缓存不会复用,等于重复下载。
典型翻车场景:
- 预加载
banner.webp?w=1200,但<img src>写的是banner.webp?W=1200(大小写差异)→ 缓存失效 - 预加载
/img/hero.jpg,但页面中引用的是./img/hero.jpg(相对路径解析不同)→ 两个独立请求 - 响应头没配
Cache-Control: public, max-age=31536000→ 即使预加载了,下次访问仍要重下
建议:所有预加载资源走绝对路径 + 哈希指纹(如 hero.a1b2c3.webp),彻底规避路径歧义。
不要用 JS 预加载替代 <link rel="preload"> 的理由
JS 预加载(如 const img = new Image(); img.src = 'xxx';)看似灵活,但有三个硬伤:
- 执行时机晚:至少要等
<script></script>标签被解析并执行,此时 HTML 主体可能已解析过半 - 无优先级控制:浏览器一律按“低优先级”处理,无法抢在 CSS 或关键 JS 前下载
- 易受阻塞:若前面有长任务(如大体积 JS 解析、同步 API 调用),
new Image()可能延后几百毫秒才执行
只有在动态路径(如用户操作后才确定图 URL)、或需要条件判断(如根据 window.devicePixelRatio 选图)时,才考虑 JS 方案,且务必搭配 img.fetchPriority = 'high'(仅 Chrome 支持)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











