<link rel="preload">是预加载首屏关键图的最佳方式,需在<head>中声明、指定as="image"、路径静态且与<img>完全一致,并建议添加fetchpriority="high";new Image()适用于运行时条件预加载,须先绑定事件再赋值src;禁用loading="lazy";WebP预加载需匹配实际使用的格式并提供fallback。

用 <link rel="preload"> 声明关键图
这是最直接、语义最准、浏览器支持最好的提前加载方式,适用于你**确定某张图会在首屏或交互初期立即使用**的场景(比如 banner、logo、登录主视觉)。它只下载不渲染,进缓存后真正 <img> 用时秒出。
必须写在 <head> 里,且满足以下条件才真正生效:
-
as="image"缺一不可——漏掉会降级为普通 fetch,失去图片特有的缓存策略和解码优化 -
href必须是静态、可解析的路径:不能含 JS 变量、模板语法(如"./images/${name}.webp"),也不能依赖当前 HTML 所在目录动态推导(比如 HTML 在/user/profile.html,却写href="./images/hero.jpg") -
fetchpriority="high"在 Chrome 101+ 有效,能抬高请求优先级;旧版忽略无副作用,建议加上
示例:
<link rel="preload" as="image" href="/assets/hero.webp" fetchpriority="high">
用 new Image() 实现运行时条件预加载
当你需要根据用户行为、设备特性或状态决定是否加载时(比如 hover 后预载下一页缩略图、按 window.devicePixelRatio 加载 @2x 版本),Image 对象是唯一可控的选择。
立即学习“前端免费学习笔记(深入)”;
关键操作顺序不能错,否则容易漏掉缓存命中时的回调:
- 先绑定
onload和onerror,再赋值src - 赋值后立刻检查
img.complete:若为true,说明已缓存,需同步执行成功逻辑 - 避免在循环中密集
new Image()——浏览器并发请求数通常只有 6~8 个,建议加 Promise 队列控制(例如每次最多 4 个)
基础封装示例:
const preloadImage = (url) => { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = () => reject(new Error(`Failed to load ${url}`)); img.src = url; });};别把 loading="lazy" 当提前加载用
loading="lazy" 是推迟加载,不是提前加载。哪怕你给首屏 <img> 显式加上它,Chrome 仍可能等到滚动前 500px 才发请求——这和“提前”目标完全相反。
常见误用包括:
- 给 banner 图加
loading="lazy",结果首屏白屏或延迟渲染 - 以为
loading="eager"就等于“提前”,其实它只是默认行为,不改变下载时机 - 混用
<link rel="preload">和loading="lazy",逻辑自相矛盾,浏览器可能忽略 preload 或延迟触发
首屏关键图必须删掉 loading="lazy",并配 <link rel="preload">。
WebP 预加载必须带 fallback
WebP 虽然体积小,但 Safari 14 之前不支持。如果你用 <link rel="preload"> 直接预加载 .webp,而实际 <img> 用的是 <picture> + <source type="image/webp"> + <img src="fallback.jpg">,那预加载的 WebP 可能根本不会被用到(浏览器按 <img src> 的 fallback 路径走)。
正确做法是:
- 只对最终会被使用的格式做 preload —— 如果
<img src>指向的是.jpgfallback,则 preload 也应指向它 - 或者,在 JS 预加载逻辑中,先检测
document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') !== -1,再决定 preload 哪个格式 - 避免为未启用的格式浪费带宽,尤其在 3G/弱网环境下
预加载不是越多越好,而是越精准越有效。最容易被忽略的点是:路径是否真能被浏览器解析、格式是否与最终渲染一致、以及是否无意中用懒加载覆盖了预加载意图。



















