不能靠 background-image 自动预加载,应使用 或 new image() 主动预加载;前者语义正确、优先级高,后者适合运行时条件判断;避免伪装 img 和赌浏览器行为,核心是确保图片提前进缓存。

不能靠 background-image CSS 声明自动预加载 —— 浏览器不会因为你在 body 或某个 div 上写了 background: url(...) 就提前拉取这张图;它只在样式计算完成、元素进入渲染流程时才发起请求,往往已错过首屏时机。
用 <link rel="preload"> 声明关键背景图
这是唯一语义正确、浏览器原生支持、且能真正提升加载优先级的方式,适用于你明确知道某张背景图会用于首屏(比如 body 或 .hero-section 的大图)。
-
as="image"必须写,否则浏览器当普通资源处理,不走图片解码和缓存逻辑 -
href要用绝对路径或基于 HTML 文档根目录的路径,例如/assets/hero-bg.webp,别写./images/bg.jpg(HTML 若在子路径下会 404) - 放在
最上方,越早声明,浏览器越早开始 fetch - 可加
fetchpriority="high"(Chrome 101+),对 banner 类背景图有效
<link rel="preload" as="image" href="/assets/hero-bg.webp" fetchpriority="high">
用 new Image() 动态预加载带条件的背景图
适合需要运行时判断的场景:比如用户切换主题后预载深色模式背景、根据 window.devicePixelRatio 加载 @2x 版本、或页面滚动到某区域前预载下一屏背景。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 必须先绑定
onload/onerror,再赋值src,否则缓存命中时事件直接同步触发,回调被跳过 - 检查
img.complete:为true表示已缓存,需立刻执行成功逻辑 - 不要在循环里密集
new Image(),浏览器并发限制通常为 6~8 个,建议用 Promise 队列控制(如每次最多 3 个) - 避免全局变量长期持有
Image实例,防止内存泄漏
const preloadBg = (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;
});
};
// 使用
preloadBg('/assets/section2-bg.jpg').then(() => {
document.querySelector('.section-2').style.backgroundImage = 'url(/assets/section2-bg.jpg)';
});
别用 display: none 或 visibility: hidden 的 <img> 元素“伪装”预加载
这种做法看似简单,实则不可靠:
- 浏览器仍按普通
<img>处理,优先级低,可能被延迟或挤出请求队列 - 如果该
<img>在 DOM 中位置靠后,或父容器有overflow: hidden,某些浏览器甚至不触发加载 - 它占 DOM 节点、触发 layout,还可能干扰 Lighthouse 性能评分
- 不如直接用
<link rel="preload">精准声明
真正关键的一点是:预加载不是“让图早点显示”,而是“让图早点进缓存”。背景图能否快速应用,取决于它是否已被浏览器下载并解码完毕。所有绕开 preload 或 Image 主动加载的取巧方式,都在赌浏览器行为,而现代浏览器的资源调度策略越来越激进——赌输的结果就是首屏闪白或布局抖动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










