预加载检测渲染函数通过闭包封装图片状态与缓存映射,利用 WeakMap 存储 URL 对应的 Promise 或 {status, img},首次调用创建 Image 并监听 onload/onerror,后续复用 Promise;渲染时查表获取结果,resolve 后插入 img 元素,reject 时降级处理;支持缓存快检(img.complete && img.naturalWidth > 0);可工厂化生成多实例隔离环境,支持 AbortController 取消及 isPreloaded 接口。

利用闭包捕获图片资源来实现“预加载检测”功能的渲染函数,核心在于:把图片加载状态(是否已缓存、是否正在加载、是否加载失败)封装进闭包,使每次调用渲染函数时能快速判断是否可直接显示,还是需等待或降级处理。
闭包封装图片加载状态与缓存映射
用一个立即执行函数创建私有作用域,内部维护一个 WeakMap 或 Map,以图片 URL 为键,值为 Promise 实例或 { status, img } 对象:
- 每个 URL 第一次被传入时,创建 Image 实例、绑定 onload/onerror,并将 Promise 存入映射表
- 后续相同 URL 调用直接复用该 Promise,避免重复请求
- Promise resolve 后保留 img 元素引用,供渲染函数即时使用
渲染函数内联检测并响应预加载结果
渲染函数本身不发起加载,而是消费闭包中已管理好的 Promise。它接收 url 和容器元素,行为如下:
- 查表获取对应 Promise;若未命中,先触发预加载再继续
- Promise resolve 后,将 img 元素插入容器、设置宽高、移除占位符
- reject 时可 fallback 到默认图、文字提示,或抛出错误供上层捕获
支持同步判定的“缓存快检”逻辑
在 Image 创建前加一层浏览器缓存试探(非 100% 可靠但实用):
- 新建 Image 后立即检查
img.complete === true && img.naturalWidth > 0 - 满足则说明已在缓存中,直接 resolve,跳过 onload 等待
- 该判断必须在设置
src之后、绑定 onload 之前 执行,否则 IE/Opera 下会漏判
带取消能力与多实例隔离的设计要点
若需支持页面多个区域独立预加载策略(如 banner 区 vs 商品列表区),可用工厂函数生成不同闭包实例:
- 每个实例拥有自己独立的 URL 映射表和并发控制逻辑
- 可选注入 AbortController,在 Promise pending 时 abort fetch(配合 createObjectURL)
- 暴露
isPreloaded(url)方法,返回 boolean,方便组件提前决策是否启用骨架屏

















