是预加载首屏关键图的最佳方式,需在中声明、指定as="image",配合fetchpriority="high"提升优先级;new image()适用于运行时条件预加载,须先绑定事件再赋值src;禁用loading="lazy"或display: none伪预加载;webp预加载需兼顾fallback策略。

用 <link rel="preload"> 声明首屏关键图
这是目前最轻量、语义最准确、浏览器支持最好的预加载方式,适用于你**确定某张图会在首屏或交互初期立即使用**的场景(比如 banner、logo、登录页主视觉)。它不渲染、不占布局、只下载进缓存,且能被 Lighthouse 正确识别为“关键资源提前获取”。
必须写在 里,越早越好;as="image" 缺一不可,否则浏览器可能降级为普通 fetch,失去图片特有的缓存和解码策略;fetchpriority="high" 在 Chrome 101+ 有效,能进一步抬高请求优先级,旧版忽略无副作用。
常见错误包括:
– href 写成动态模板如 "/assets/${name}.webp",实际会当字面量请求导致 404
– 相对路径没考虑 HTML 文件位置,比如 HTML 在 /user/profile.html,却写 href="./images/hero.jpg",应改为 href="/images/hero.jpg" 或绝对路径
– 把它当成懒加载开关,加了 loading="lazy" 还配 preload,逻辑自相矛盾
用 new Image() 实现运行时条件预加载
当你需要根据用户行为、设备特性或状态判断是否预加载时(比如 hover 后预载下一页缩略图、按 window.devicePixelRatio 加载 @2x 版本),Image 对象是唯一可控的选择。
关键操作顺序不能错:
– 先绑定 onload 和 onerror,再赋值 src,否则缓存命中时事件直接同步触发,回调会被跳过
– 检查 img.complete:如果为 true,说明已缓存,需立刻执行成功逻辑
– 避免在循环中密集 new Image(),浏览器并发请求数有限(通常 6~8 个),建议加队列或 Promise 控制并发数(例如每次最多 4 个)
基础封装示例:
const preloadImage = (url) => {<br> return new Promise((resolve, reject) => {<br> const img = new Image();<br> img.onload = () => resolve(img);<br> img.onerror = () => reject(new Error(`Failed to load ${url}`));<br> img.src = url;<br> });<br>};
别把 loading="lazy" 或 display: none 当预加载用
loading="lazy" 是推迟加载,不是提前加载。哪怕你给首屏 <img> 显式加上它,Chrome 仍可能等到滚动前 500px 才发请求——这和预加载目标完全相反。loading="eager" 只是“不懒”,不等于“提前”;decoding="async" 只影响解码时机,和下载无关。
用 display: none 或 opacity: 0 的 <img> 伪预加载问题更隐蔽:
– 它会占用 DOM 节点、触发完整渲染流程(含 layout、paint),增加主线程负担
– 在部分移动端 WebView 中,隐藏 <img> 可能被跳过解码,导致后续展示时卡顿
– Lighthouse 会把它标为“隐藏但关键资源”,拖累性能评分
– 不支持监听加载状态,失败无法感知
WebP 预加载必须带 fallback,且优先级要权衡
如果你用 <link rel="preload"> 加载 WebP,而页面实际通过 <picture></picture> + <source type="image/webp"></source> 切换格式,那没问题;但若后端或 CDN 无法稳定提供 WebP(比如旧 Android WebView 不支持),就必须准备 fallback —— 不能只 preload WebP 却让降级 JPG 完全靠运行时发现。
做法上:
– 同时 preload 主力格式(如 WebP)和 fallback 格式(如 JPG),但给 JPG 更低的 fetchpriority(或干脆不设)
– 或者只 preload fallback 格式,靠 <picture></picture> 的现代语法自动选最优,避免多 preload 带来的带宽浪费
– 注意:preload 的 URL 必须和最终 <img> 或 <source></source> 的 src 匹配,否则缓存不会复用
真正容易被忽略的是资源优先级冲突:如果你 preload 了 10 张图,又同时 prefetch 下一页 HTML,浏览器可能因并发限制把部分图片请求压到很后面,结果首屏图反而没抢到带宽。这时候得靠 fetchpriority 或分批控制节奏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











