是唯一可靠且无需js的预加载方式,它不渲染、只缓存图片,需写as="image"和静态href,chrome 101+支持fetchpriority="high";动态场景须用new image()并注意事件绑定顺序与并发控制。

直接用 <link rel="preload"> 声明关键图,是唯一既可靠又无需 JS 就能生效的预加载方式;其他所谓“预加载”手段,要么无效(如 loading="lazy"),要么控制力弱(如 CSS background 伪加载)。
为什么 <link rel="preload" as="image"> 是首选
它不渲染、不占布局,只把图片下进缓存,且被所有现代浏览器原生支持。Lighthouse 能识别,CDN 和 HTTP/2 推送也能配合生效。
-
as="image"必须写 —— 缺了浏览器会当普通 fetch 处理,失去图片专用缓存和解码策略 -
href必须是静态路径 —— 相对路径基于 HTML 文件位置解析,比如 HTML 在/user/profile.html,就别写./images/hero.jpg,应写/images/hero.jpg或绝对 URL -
fetchpriority="high"在 Chrome 101+ 有效 —— 能抬高请求优先级,旧版忽略无副作用 - 不能在
href里写模板变量,如"/assets/${name}.webp",浏览器会当字面量请求,大概率 404
什么时候必须用 new Image()
当你需要根据运行时条件决定是否加载:比如用户 hover 某按钮后预载下一页缩略图、按 window.devicePixelRatio 加载 @2x 版本、或轮播图中只预载当前页及相邻 1–2 张。
- 顺序不能错:先绑定
onload/onerror,再赋值src—— 否则缓存命中时事件同步触发,回调会被跳过 - 必须检查
img.complete:如果为true,说明已缓存,需立刻执行成功逻辑 - 避免密集
new Image():浏览器并发请求数通常只有 6~8 个,建议限制并发(例如每次最多 4 个) - 不要用
new Image().src = url简写 —— 它无法捕获失败,也无法链式等待
loading="lazy" 不是预加载,是反效果
这是最常踩的坑。哪怕你给首屏 <img> 显式加上 loading="lazy",Chrome 仍可能等到滚动前 500px 才发请求 —— 完全违背预加载目标。
-
loading="eager"只是“不懒”,不等于“提前” -
decoding="async"只影响解码时机,和下载无关 - 如果你发现某张图“怎么还没出来”,第一反应不该是加预加载,而是检查是否误用了
loading="lazy"
真正难的是权衡:预加载太多浪费带宽,太少又卡切换;<link rel="preload"> 无法动态判断设备特性,new Image() 又得自己控并发和错误兜底。实际项目里,这两者往往得配合用 —— 首屏关键图用 preload,交互态资源用 Image 对象按需触发。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











