new image()预加载失败主因是未正确触发加载:漏设src、src为空或路径错误、循环中未保留引用致回收;须先绑onload/onerror再赋src,并确保url有效。

预加载图片不是“提前把所有图都拉一遍”,而是有策略地让关键图在用户看到前就进缓存——做对了,首屏秒出;做错了,反而拖慢首屏、浪费带宽。
用 new Image() 预加载时,为什么图片没进缓存?
常见错误是只创建 Image 对象却没真正触发加载:比如忘了赋值 src,或赋值后立即丢弃引用(尤其在闭包/循环中未保留变量)。浏览器对无引用的 Image 实例可能回收其下载通道。
- 必须显式设置
img.src = url,且该 URL 不能为空、不能是相对路径未解析成功的结果 - 避免在 for 循环里直接写
img.onload = () => {...}而不绑定正确上下文,容易所有回调共享最后一个url - 不需要插入 DOM,但建议监听
onload和onerror,失败时可降级或上报 - 示例片段:
function preload(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; // 这行不能少,也不能放错位置 }); }
用 CSS background 预加载,哪些场景会失效?
CSS 预加载靠的是浏览器解析样式时顺带下载背景图,但它依赖“样式被计算并应用”这一过程。如果元素被 display: none、visibility: hidden 或父容器未渲染,部分浏览器(尤其是旧版 Safari 和某些 WebView)可能跳过资源请求。
- 最稳妥做法:用一个固定尺寸、绝对定位、透明且不遮挡内容的
div,例如width: 1px; height: 1px; opacity: 0; - 不要依赖
class动态添加后再设 background —— class 添加时机不可控,可能晚于样式计算 - 路径必须与最终使用的完全一致(含协议、大小写、查询参数),否则缓存不命中
- 不适用于需要按需加载大量图的场景:CSS 方式是一次性声明,无法控制并发、超时或失败重试
使用 queryLoader2 或 jquery.LoadImage 时,最容易被忽略的配置项
这类插件封装了流程,但默认行为常与直觉不符。比如 queryLoader2 的 minimumTime 默认是 300ms,意味着即使所有图瞬间加载完,覆盖层也会强制停留 300ms —— 在快速网络下反而制造卡顿感。
-
deepSearch: true会遍历所有img、background-image、甚至内联 style,可能抓到你根本不想预加载的广告图或埋点像素图 -
jquery.LoadImage底层用$.ajax,默认发送Accept: */*请求头,某些 CDN 或图片服务会因此返回非图像响应(如 HTML 错误页),导致预加载静默失败 - 务必检查插件是否自动处理 404:多数不会,
onerror回调缺失会导致后续图片加载队列中断 - 若页面已启用 HTTP/2 Server Push,再用 JS 预加载可能重复请求,反而增加竞争
真正关键的不是“用了什么技术”,而是“哪几张图值得预加载”。首页 banner、登录页头像、核心操作按钮图标——这些才该进预加载队列;而列表页的几十张缩略图,更适合懒加载。缓存容量有限,策略比工具重要得多。











