预加载图片不节省流量,而是针对确定性场景的资源调度:仅当图片1秒内必显、无法懒加载、尺寸格式已收敛时才适用;否则应优先使用三件套(宽高、srcset/sizes、loading属性)实现精准加载。

预加载图片本身不节省流量,反而会增加请求——关键在于“只预加载真正需要的、且用对方式”。盲目用 <link rel="preload"> 或 new Image() 拉图,和直接写 <img> 没区别,甚至更糟(多一次无展示的下载)。
什么时候该预加载?先问三个问题
预加载不是优化手段,而是对确定性行为的资源调度。以下任一为否,就不该预加载:
- 这张图是否在用户进入页面后 1 秒内必然展示(如首屏 banner、登录页 logo)?
- 这张图是否 无法被懒加载覆盖(比如它不在滚动流里,而是固定位置的引导图)?
- 这张图是否 尺寸/格式已收敛,不会因设备或网络动态切换而重复拉取?
如果答案有任一“否”,优先用 loading="eager" + 正确 srcset/sizes,而不是预加载。
<link rel="preload"> 必须配 as="image" 和静态路径
不写 as="image",浏览器就按普通 fetch 处理:不走图片解码管线、不进图片缓存池、可能被降级为低优先级——等于白写。同时,href 必须是纯字符串,不能含 JS 变量或模板语法,例如 href="/assets/${name}.webp" 会被当字面量请求,404 后仍计入失败流量。
常见错误:
- 把
<link rel="preload">放在里 —— 浏览器 preload scanner 不会扫描 body,资源发现延迟 - 用相对路径如
./images/hero.jpg却没确认 HTML 当前路径,导致 404 流量白耗 - 给非首屏图加 preload,比如列表页第 5 张缩略图,用户大概率不点,预加载即浪费
用 new Image() 动态预加载时,必须加网络兜底
运行时预加载(如 hover 后预载下一页图)看似可控,但极易在弱网下失控。iOS Safari 在 2G 下会静默限制并发请求数,Chrome 在节电模式下可能丢弃请求——你调了 img.src = url,不代表它真发出了。
安全做法:
- 先检查
navigator.connection?.effectiveType,值为'2g'或'slow-2g'时,跳过预加载或强制降级为metadata级别(如只拉缩略图) - 监听
onload和onerror,失败时不重试,避免雪崩 - 赋值
src前,先绑定事件;否则缓存命中时事件同步触发,回调直接丢失 - 避免循环中密集
new Image(),浏览器并发上限通常为 6~8,建议用 Promise 队列控制(如每次最多 3 个)
真正省流量的是“不预加载”,而是精准加载
大部分场景下,最省流量的方案是:不用任何预加载,只靠 <img> 自身属性组合。
核心是三件套共存:
-
width和height(或 CSSaspect-ratio),让浏览器提前预留空间,避免回流重排 -
srcset+sizes,确保弱网下拉小图、高清屏拉大图,不浪费带宽 - 首屏图用
loading="eager"(可省略,默认即 eager),非首屏图用loading="lazy"
注意:loading="lazy" 在 iOS 15.4 以下无效,Safari 会直接加载;若服务端渲染(SSR)未正确注入 loading 属性,也可能被忽略。所谓“省流量”,本质是让浏览器在正确时机、用正确尺寸、加载真正需要的那张图——预加载只是其中极窄的例外,不是默认选项。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











