是唯一可靠方案,因其不依赖js、不额外发请求、seo友好且浏览器原生支持格式协商;关键在于按顺序匹配首个支持且可解码的type,必须作为强制兜底且src为静态直访路径,type值须严格匹配标准mime(如image/webp),服务器content-type也须完全一致。

直接用 <img src="x.webp"> 在 Safari ≤13.1、IE、旧版 Android WebView 中会白屏,不是“加载慢”,是浏览器压根不识别 image/webp MIME 类型,连请求都不发。
为什么 <picture></picture> 是唯一可靠方案
它不依赖 JS,不额外发请求,SEO 友好,且浏览器原生支持格式协商。关键在于:<source></source> 按顺序匹配,遇到第一个 type 支持且资源可解码的就停,<img> 仅在所有 <source></source> 都不满足 media 条件时才生效——但你必须把它当作强制兜底来用,不能省略。
-
type值必须严格匹配标准 MIME:写image/webp,不能写webp或image/jpg(正确应为image/jpeg) - 服务器返回的
Content-Type必须和<source type></source>完全一致,否则 Safari 直接跳过 - AVIF 要放最前:
<source srcset="a.avif" type="image/avif"></source>;WebP 次之;JPEG/PNG 必须落在<img src>里,不能写成第三个<source></source> -
<img>的src必须是静态可直访路径,比如logo.jpg,不能是logo.jpg?format=webp或 CDN 动态转码地址
<img> 单标签的降级陷阱
它无法自动 fallback 到其他格式。哪怕你用 CDN 把 logo.jpg 动态转成 WebP,不支持的浏览器仍会收到 406 错误或损坏数据,最终白屏。
- 适合场景:图标、头像、背景图(
background-image: url(x.webp)),这些地方不需要响应式或艺术方向控制 - 纯 CSS 背景图无法做格式回退,
background-image不识别type或srcset - IE 和部分旧 WebView 会完全忽略
<picture></picture>,只渲染内部<img>—— 这反而是优势,前提是<img src>真实可用 - 别给
<img>加srcset或sizes,它只负责兜底,不是响应式主力
所有格式图片必须尺寸与构图一致
如果 WebP 版是 800×600 裁剪,JPEG 版是原始 1200×800,切换时页面会突然拉伸或留白,用户感知就是“闪跳”。这不是 bug,是设计遗漏。
- 宽高、裁剪比例、色彩空间(sRGB)必须统一,否则视觉跳变更难调试
-
fetchpriority="high"要加在<img>上,加在<source></source>上无效 - 旧 Android WebView(如 4.4)对
srcset支持极差,建议用data-srcset+ JS 检测后动态赋值,比纯 HTML 更可控 -
alt属性不可省,否则无障碍和 SEO 全挂,且所有格式图片的alt文本必须一致
当 <source></source> 全部加载失败时怎么办
浏览器不会自动 fallback 到 <img>,因为 <source></source> 的 media 条件可能满足,只是资源 URL 失效或格式损坏。此时 <img> 不会被触发,页面留白。
- 给
<img>加onerror内联处理是最轻量解法:onerror="this.src='/fallback.jpg'; this.onerror=null;" -
onerror只监听<img>自身src失败,不监听<source></source>,所以它只保底,不替代<picture></picture>结构 - 复杂项目建议用 JS 全局监听:
document.querySelectorAll('picture img')绑定error事件,失败后替换src并上报日志 - 不要指望
<noscript></noscript>补救——它只在 JS 被禁用时生效,而图片降级失败是 HTML/CSS 层问题
最容易被忽略的点:所有格式图片的尺寸、构图、宽高比、MIME 声明、服务器响应头,必须全部对齐。少一个环节,降级就变成随机失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











