preload适用于当前页面马上要用的关键图片,如首屏lcp元素、banner图,需用声明并确保url精确匹配;prefetch仅适合后续页面可能用到的低优先级资源。

图片预加载不是加个 <link rel="preload"> 就完事的——它得和实际渲染时机、资源优先级、浏览器兼容性对齐,否则可能拖慢首屏。
什么时候该用 preload 而不是 prefetch
preload 是告诉浏览器“这个资源我马上就要用”,会以高优先级下载;prefetch 是“将来可能用”,优先级低,甚至可能被丢弃。首页轮播图第一张图、关键 banner 图、LCP 元素对应的图片,必须用 preload。
- 用
<link rel="preload" as="image" href="hero.jpg">放在里,且确保href路径准确(相对路径需相对于当前 HTML 文档) - 别对所有
<img>都写preload:浏览器不支持重复 preload 同一资源的去重,反而增加解析开销 -
prefetch适合下一页的图片(比如分页列表第二页的缩略图),但别指望它一定加载成功
loading="eager" 和 fetchpriority="high" 的实际效果
这两个属性作用于 <img> 标签本身,是更细粒度的控制,但依赖现代浏览器支持(Chrome 77+、Edge 105+,Firefox 112+ 开始支持 fetchpriority)。
-
loading="eager"强制取消懒加载,让图片立即发起请求,但不会提升网络优先级 -
fetchpriority="high"才真正影响 Chromium 内核的资源调度队列——和preload效果接近,但只对本标签生效,且无法跨资源复用 - 二者可共存:
<img src="main.jpg" loading="eager" fetchpriority="high">,比单纯src加载快约 100–300ms(实测 LCP 提前) - 注意:如果图片在视口外又设了
eager,可能造成带宽浪费,尤其移动端
JavaScript 预加载要避开常见陷阱
用 JS 创建 Image 实例看似灵活,但容易误用导致资源冲突或内存泄漏。
- 不要在循环里反复 new
Image()却不保存引用——GC 可能延迟清理,图片缓存未命中时还会重复请求 - 正确做法是显式监听
load和error:const img = new Image(); img.src = 'thumb.jpg'; img.onload = () => console.log('loaded'); img.onerror = () => console.error('failed'); - 避免预加载尚未确定是否会被渲染的图片(例如 tab 切换后才显示的内容),应结合用户行为触发,比如
mouseenter后再加载对应 tab 的图 - Service Worker 场景下,JS 预加载的图片不会自动进 Cache Storage,需手动
cache.put()
最易被忽略的一点:预加载资源若与实际 <img src> 的 URL 字符串不完全一致(比如 query 参数顺序不同、有无尾部斜杠、大小写差异),浏览器会当作两个资源处理,白忙一场。上线前务必用 DevTools 的 Network 面板确认预加载项是否命中了最终渲染的请求。











