关键图片必须用<picture>+可靠<img>回退,其src须为绝对路径默认图;<source>按AVIF→WebP顺序排列;onerror仅适简单场景,全局error委托更适中大型页面;弱网需fetch+AbortController主动超时控制。

关键图片必须用 <picture> + 可靠 <img> 回退
单纯写 <img src="critical.jpg"> 没有降级能力,一旦 404 或跨域拦截,用户只看到 alt 文字甚至空白。真正的降级起点是结构层:把关键图放进 <picture>,且其内部的 <img> 的 src 必须指向一个 100% 可访问的默认图(比如 CDN 上的占位图或业务主图),不能是相对路径、空值或临时路径。
常见错误是把 <img> 当作“备用 source”来写无效地址,结果所有 <source> 失败后,<img> 自己也加载失败,整个区域退化为纯文本。
-
<source>顺序按现代→旧版排:<source type="image/avif">→<source type="image/webp">→<img> -
<img>的src必须带协议或根路径(如/assets/fallback.jpg),避免因 HTML 入口位置变动导致路径失效 - Safari 不认没
type的<source>,漏写会跳过整条分支
用 onerror 动态修正失败请求(轻量但需防重复)
如果默认图需根据主题、语言或设备动态切换,可在 <img> 上加 onerror 内联处理。它比全局 JS 监听更轻、兼容性更好(IE9+),但仅适合简单场景。
注意:多次触发时可能反复请求同一失败地址,造成冗余网络行为;也不适用于 srcset 复杂响应式逻辑。
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 写法示例:
<img src="broken.jpg" onerror="this.src='/assets/brand-logo-dark.svg'"> - 避免在
onerror中调用函数或读取外部变量,防止执行上下文丢失 - 不要对同一元素连续设置多个
onerror,后者会覆盖前者
全局监听 error 事件做统一降级(适合中大型页面)
当页面有几十张关键图,且需集中控制 fallback 行为(比如打点、灰度开关、CDN 切换),应改用事件委托——监听 document 上的 error,过滤出 <img> 并修正。
这样能复用逻辑、避免内联污染,也方便后续接入监控系统。但要注意:它依赖 JS 加载完成,弱网下若 JS 还没执行,首次错误仍会暴露。
- 必须用
event.target判断是否为<img>,不能只靠选择器,否则可能误伤其他资源 - 修正前建议检查
event.target.naturalWidth === 0,排除已加载成功但尺寸为 0 的异常情况 - 降级图 URL 建议走配置中心或环境变量,而非硬编码,便于 A/B 测试
弱网下要防“假成功”:用 AbortController 主动中断卡住的图片请求
某些弱网环境(如高丢包率移动网络)下,<img> 的 onerror 根本不触发,因为请求卡在 pending 状态,浏览器不认为失败。这时得靠 JS 主动干预。
目前没有原生 API 能 abort 图片加载,但可用 fetch + Blob + URL.createObjectURL 替代 <img src>,并配合 AbortController 设置超时(推荐 3s)。虽然多一层转换,但能真正掌控生命周期。
- 超时后立即切换为本地缓存的 base64 占位图,避免白屏
- 注意
URL.createObjectURL生成的地址需手动revoke,否则内存泄漏 - 该方案不适合大量图片同时加载,优先用于首屏 2–3 张核心图
<source> 靠 MIME 类型和媒体查询,<img> 靠 URL 可达性,JS 监听靠 naturalWidth,fetch 靠 AbortController。混用不同机制时,最容易忽略的是它们的触发时机差异。


















