图片预加载只有两种可靠方式:一是用声明静态关键资源,须置于且路径静态;二是用new image()运行时条件加载,需先绑定事件再赋值src并检查complete。

图片预加载不是靠 <img> 标签自动完成的,loading="lazy" 是推迟加载,decoding="async" 只影响解码时机——真要提前拿图进缓存,只有两种可靠路径:<link rel="preload"> 声明静态关键资源,或用 new Image() 在运行时可控触发。
用 提前声明首屏关键图
这是最轻量、语义最准、Lighthouse 可识别的预加载方式,适用于 banner、logo、登录页主视觉等你确定「一打开就要显示」的图。
-
as="image"必须写,缺了浏览器会当普通 fetch 处理,无法启用图片专属缓存和解码策略 - 必须放在
里,越早越好;动态插入(比如 JS 创建后 append)无效 -
fetchpriority="high"对 Chrome 101+ 有效,能抬高请求优先级;旧版忽略无副作用 - href 必须是静态路径,不支持
${name}.webp这类模板语法,也不支持相对路径错位(比如 HTML 在/user/下却写./images/hero.jpg) - 它只下载不渲染、不占布局、不触发 onload——适合“确保进缓存”,但不管“何时展示”
用 new Image() 实现运行时条件预加载
当你需要根据用户行为、设备像素比或模块状态决定是否加载时(比如 hover 后预载下一页缩略图),new Image() 是唯一可控的选择。
- 顺序不能错:先绑定
onload/onerror,再赋值src;否则缓存命中时事件同步触发,回调直接跳过 - 必须检查
img.complete:为true说明已缓存,需立刻执行成功逻辑 - 避免在循环里密集
new Image()——浏览器并发请求数通常限 6~8 个,建议用 Promise 队列控制(例如每次最多 4 个) - 不要用
new Image().src = url简写,它无法捕获失败,也无法链式等待
别把 loading="lazy" 或 display: none 当预加载用
这是最常见的误用。设置了 loading="lazy" 的首屏图,Chrome 仍可能延迟到滚动前 500px 才发请求;而 display: none 的 <img> 虽然会触发下载,但会占用 DOM、干扰 Lighthouse 评分,且无法监听状态。
-
loading="eager"是默认行为,显式写出来只是“不懒”,不等于“提前” -
decoding="async"只控制解码是否阻塞主线程,和下载时机完全无关 - 用
<picture></picture>或srcset时,如果没配sizes,浏览器可能瞎猜宽度,导致手机端下了一张桌面尺寸大图 - 首屏关键图必须删掉
loading="lazy",并搭配<link rel="preload">显式声明
真正难的是权衡:preload 太多会抢占带宽,影响首屏渲染;new Image() 并发失控会触发请求节流;WebP 预加载还得配 fallback。这些细节不写死在构建流程或运行时策略里,很容易上线后才发现 banner 加载变慢了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











