是首选,因其仅下载进缓存、不渲染不占布局,配合as="image"可优化请求优先级与解码策略,且被lighthouse认定为关键资源提前获取;href须为静态绝对路径,否则易404或缓存失效。

用 <link rel="preload"> 声明关键图是最直接、最可控的方式,其他方法要么不可靠,要么根本不是预加载。
为什么 <link rel="preload"> 是首选
它不渲染、不占布局、只下载进缓存,浏览器能据此优化请求优先级和解码策略。Lighthouse 也认它为“关键资源提前获取”。as="image" 缺一不可——漏掉这个,浏览器会当成普通 fetch,缓存和解码都走默认逻辑,失去预加载意义。
-
href必须是静态路径,不能含 JS 变量或模板语法,比如"/assets/${name}.webp"会直接 404 - 相对路径按 HTML 文件位置解析,
./images/hero.jpg在/user/profile.html里会错配成/user/images/hero.jpg,建议统一用绝对路径 -
fetchpriority="high"在 Chrome 101+ 有效,旧版忽略无副作用,但能抬高首屏图的请求权重
new Image() 适合什么场景
当你需要根据用户行为、设备像素比或轮播位置动态决定加载哪张图时,new Image() 是唯一可靠选择。它能监听成功/失败,也能配合缓存命中判断(img.complete)立刻执行后续逻辑。
- 必须先绑定
onload/onerror,再赋值src;否则缓存命中时事件同步触发,回调直接跳过 - 大量预加载时别在循环里密集
new Image(),浏览器并发限制通常为 6~8 个,建议控制在每次最多 4 个 - URL 必须完全一致:轮播图中若用
slide-1.jpg?v=2024预加载,切换时也得用相同带参 URL,否则缓存不命中
哪些做法根本不是预加载
loading="lazy" 是推迟加载,不是提前加载。哪怕你给首屏 <img> 显式加了它,Chrome 仍可能等到滚动前 500px 才发请求——这和预加载目标完全相反。loading="eager" 只是“不懒”,不等于“提前”;decoding="async" 只影响解码时机,和下载无关。
-
display: none或 CSSbackground伪隐藏,无法监听加载状态,且会随页面一起加载,拖慢首屏 - 把
<img>标签写死在 HTML 里(没做任何控制),只是让浏览器按默认策略并行下载,不属于“预加载”行为 - 用
fetch()下载图片 blob 再转URL.createObjectURL(),容易内存泄漏,且需手动释放,复杂度远超必要
真正难的是权衡:首屏关键图用 <link rel="preload">,交互触发图用 new Image(),而所有非关键图必须明确排除在预加载之外——多加载一张,就多浪费一次 TCP 连接和缓存空间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











