预加载图片超载本质是资源调度失控,应剔除非首屏、非确定性、非静态路径的预加载项,并用并发控制兜底;列表页第3张后的缩略图等低点击率图片绝对不该加link rel="preload"。

预加载图片超载不是“加载太多”,而是“不该预加载的图被加了 preload”,本质是资源调度失控。解决方向很明确:砍掉非首屏、非确定性、非静态路径的预加载项,再用并发控制兜底运行时逻辑。
哪些图片绝对不该加 link rel="preload"
浏览器对 link rel="preload" 不做语义判断,你写它就发请求——哪怕用户根本不会看到那张图。
- 列表页第 3 张之后的缩略图(用户点击率通常
- 折叠区域里的图(
display: none或hidden属性控制) - 由 Vue/React 动态渲染的
img(初始 HTML 里不存在,preload scanner 根本扫不到) - 带
loading="lazy"的图(语义冲突:一边说“等我滚到再下”,一边又“现在就抢带宽”)
new Image() 并发超载怎么压住
JS 主动预加载容易在循环或事件中失控,尤其用户快速 hover 多个卡片时,new Image() 可能瞬间发起 20+ 请求,但浏览器实际并发上限只有 6~8 个,其余排队或直接丢弃。
- 必须用 Promise 队列节流,例如每次最多并发 3 个:
Promise.allSettled(batch)控制批次 - 赋值
src前,先检查navigator.connection?.effectiveType,值为'2g'或'slow-2g'时直接跳过 - 避免
for (let url of urls) { new Image().src = url }这类写法——事件监听全丢失,失败无声无息
href 路径错误导致的隐性超载
相对路径写错、模板变量混入、404 后仍计入请求数,这些都会造成“白跑流量”。关键不是多下了几张图,而是多发了无效请求,还占了缓存位和连接池。
立即学习“前端免费学习笔记(深入)”;
-
href必须是纯静态字符串,href="/assets/${name}.webp"会被当字面量请求,返回 404 也计流量 - HTML 在
/user/profile.html,却写href="./images/hero.jpg"→ 实际请求/user/images/hero.jpg,404 - 没写
as="image":浏览器按普通 fetch 处理,不进图片缓存池,后续真正img标签还是会重下
最常被忽略的一点:预加载本身不省流量,它只换时间。真正省流量的是“不预加载”,而是靠 srcset+sizes+loading="eager" 精准供给首屏图——别把调度手段当成压缩手段。



















