<link rel="preload">是预加载首屏关键图的最佳方式,须在<head>中声明、指定as="image"、用静态绝对路径,并配fetchpriority="high";new Image()适用于运行时条件预加载,需先绑事件再赋值src,并控制并发。

预加载图片不是加个 loading="lazy" 就完事,真要见效,得看资源是否进缓存、是否在关键路径上被及时使用、浏览器有没有把它当回事——否则预加载就成空转。
用 <link rel="preload"> 声明首屏核心图必须写对位置和属性
这个标签只在 <head> 里生效,且必须早于所有 JS 和样式表。它不渲染、不占布局,只告诉浏览器:“这张图马上要用,请优先下载”。
-
as="image"缺一不可:没它,浏览器按普通 fetch 处理,不会走图片的缓存策略和解码逻辑 -
href必须是静态绝对路径(如/assets/hero.webp),不能带模板变量或相对路径误算(比如 HTML 在/user/profile.html却写./images/hero.jpg) -
fetchpriority="high"对 Chrome 101+ 有效,能抬高请求优先级;旧版忽略,无副作用 - 别跟
loading="lazy"混用:一个要提前拿,一个要推迟拿,浏览器会困惑,可能直接跳过预加载
用 new Image() 实现运行时条件预加载要注意事件绑定顺序
适合 hover 后加载下一页缩略图、根据 window.devicePixelRatio 选 @2x 图、或用户进入某模块才触发的场景。但错一步,就收不到成功或失败信号。
- 必须先绑
onload和onerror,再赋值src;否则缓存命中时事件同步触发,回调直接丢失 - 赋值后立刻检查
img.complete:为true表示已缓存,需手动执行成功逻辑 - 避免循环中密集
new Image():浏览器并发请求数通常卡在 6~8 个,建议用 Promise 队列控制(如每次最多 4 个) - 别写
new Image().src = url这种简写——失败无法捕获,也无法 await
WebP 预加载必须配 fallback,且不能只靠 <picture>
<link rel="preload"> 不支持格式协商,它只认一个 URL。如果你预加载的是 WebP,但用户浏览器不支持(比如 Safari 13 以下),那就真的一张图都看不到。
立即学习“前端免费学习笔记(深入)”;
- 预加载 WebP 的同时,必须在对应
<img>或<picture>中提供 JPEG/PNG fallback,且 fallback 资源也得进缓存才不白忙 - 不要以为写了
<source type="image/webp">就够了:<link rel="preload">不解析<picture>结构,它只管自己那个href - 如果 fallback 图体积大,考虑用
fetchpriority="low"降权,避免挤占首屏关键资源带宽
最常被忽略的点是:预加载 ≠ 自动展示。你用 <link rel="preload"> 下好了,但 <img src="/assets/hero.webp"> 的路径如果拼错、MIME 类型不对、或服务端没开 WebP 支持,浏览器照样不会从缓存取——它只会重新发一个带错误头的请求,然后失败。预加载只是把资源“放门口”,开门还得靠后续真实请求的路径、协议、响应头全部对得上。



















