<link rel="preload">是唯一真正可控、语义明确、浏览器原生支持的图片预加载方式;它仅适用于首屏确定渲染、URL静态且与<img src>完全一致的关键图片,而new Image()适用于hover、设备像素比等运行时条件预加载,需先绑事件再赋值src并控制并发。

link rel="preload" 是唯一真正可控、语义明确、浏览器原生支持的图片预加载方式;其他所谓“预加载”手段,比如 loading="lazy"、display: none 或 CSS background-image 伪隐藏,要么是延迟加载,要么不可靠、不触发缓存复用,实际等于没做。
什么时候必须用 link rel="preload"?
只在以下三个条件同时满足时才该用:
– 图片确定会在首屏(或用户进入后 1 秒内)渲染,比如 banner、logo、登录框主图;
– 图片 URL 是静态且确定的,不会因设备像素比、网络类型或用户状态动态变化;
– 对应的 <img src> 标签路径与 href 完全一致(包括大小写、斜杠、query 参数)。
不满足任一条件,就别硬上 preload——它不会省流量,反而可能挤占关键资源带宽。
new Image() 适合哪些场景?
当你需要运行时判断是否加载时,new Image() 是唯一可行方案:
– 用户 hover 商品卡片后预加载详情页大图;
– 轮播图滑到第 2 页时,提前拉取第 4、5 页缩略图;
– 检测 window.devicePixelRatio === 2 后加载 @2x 版本。
关键操作顺序不能错:
– 先绑定 onload 和 onerror,再赋值 src;
– 赋值前检查 img.complete,为 true 说明已缓存,需立刻执行成功逻辑;
– 并发数控制在 3~4 个以内,避免触达浏览器同域并发上限(通常 6~8 个)。
最容易踩的坑:路径、时机、缓存三不匹配
预加载失效最常见原因不是语法错,而是三处不一致:
– href 写了相对路径如 ./images/hero.jpg,但 HTML 文件在 /user/profile.html 下,导致 404;
– preload 的 href="/assets/logo.webp",而 <img src="/assets/logo.png">,缓存无法命中,白下一次;
– 把 link 放进 <body> 或动态插入,浏览器 preload scanner 不扫描,请求根本不会发起。
验证是否生效,直接看 Network 面板:过滤 Preload 类型请求,确认状态码是 200 且 Timing 中有 start 时间早于 DOMContentLoaded。



















