是唯一零js、原生、seo友好的webp/avif降级方案;失效主因是type与content-type不匹配、顺序错误(avif→webp→jpeg)、或缺失必需的兜底。

直接用 <picture></picture>,别绕弯子——这是唯一零 JS、不发额外请求、SEO 友好、原生支持的方案。
为什么 <source type="image/webp"></source> 写了却还是加载 JPEG
不是浏览器“不支持”,而是链路中某处 MIME 类型没对上。浏览器只认标准 type 字符串,且必须和服务器返回的 Content-Type 响应头完全一致。
-
type="webp"或type="image.webp"—— 缺image/前缀或用错分隔符,直接跳过该<source></source> - 服务器返回
Content-Type: text/plain或空,Nginx 未配置types { image/webp webp; } - CDN 没透传
Accept: image/webp请求头,后端无法判断客户端能力,统一返回 JPEG - DevTools Network 面板里看到状态是
blocked:mime-type或406 Not Acceptable,基本可定位到服务端配置问题
<source></source> 的顺序为什么不能调换
浏览器从上到下逐个尝试 <source></source>,遇到第一个 type 可解码且 media 条件满足的就加载并停止。这不是“建议顺序”,是执行逻辑本身。
-
image/avif必须放最前:<source srcset="a.avif" type="image/avif"></source> -
image/webp居中:<source srcset="a.webp" type="image/webp"></source> - JPEG/PNG 回退必须放在
<img>的src属性里,不能写成第三个<source></source> - 把
<source type="image/jpeg"></source>放在 WebP 前面,哪怕设备支持 WebP,也永远加载不到
<img> 的 src 必须指向真实可用的 JPEG/PNG
<picture></picture> 本身不加载图片,真正触发加载的是内部匹配成功的 <source></source> 或必需的 <img>。没有 <img>,就不会渲染任何内容,也不会发请求。
-
<img>不是“备用 source”,而是所有不支持type的老浏览器(如 IE、旧 Android WebView)唯一能识别的入口 -
<img src>不能是带查询参数的动态地址(如?format=webp),也不能是 404 路径;否则整个<picture></picture>会退化为仅显示alt文本 - 首屏关键图应在
<img>上加fetchpriority="high",提升 LCP;加在<source></source>上无效 - 所有格式的图片必须尺寸一致、构图一致,否则响应式切换时会出现拉伸或视觉跳变
WebP 在 CSS 里没法做格式回退
background-image: url(x.webp) 这种写法没有任何降级能力。CSS 不识别 type 或 srcset,也不触发浏览器的格式协商机制。
- 想让背景图也支持 WebP → JPEG 回退,只能靠服务端内容协商(需后端配合 Accept 头判断 + 动态返回),前端无解
- 图标、头像等静态资源可用
<img>单标签 + CDN 动态转码(如icon.jpg?x-oss-process=image/format,webp),但必须确保不支持 WebP 的浏览器拿到的是 JPEG,而非 406 或损坏数据 - 纯 CSS 方案本质是放弃格式协商,只适合对兼容性要求极低或已明确用户环境的场景
真正难调的不是语法,而是不同设备对 media 查询的解析差异、CDN 对 Accept 头的透传策略、以及图片服务返回的 Content-Type 是否和 <source type></source> 完全一致——这些地方最容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











