必须用 <picture> + <source> 实现 WebP 条件加载,<source type="image/webp"> 是关键判断依据,<img> 为兜底且不可省略;直接 <img src="xxx.webp"> 会导致不支持浏览器显示空白。

WebP 图片在 HTML 中怎么写才真正生效
直接用 <img src="xxx.webp"> 是最常见错误——它在不支持 WebP 的浏览器里会显示空白或报错,不是“降级失败”,而是根本没 fallback 机制。
必须用 <picture> + <source> 才能实现真正的条件加载:
<picture> <source srcset="logo.webp" type="image/webp"> <img src="logo.png" alt="logo"> </picture>
-
type="image/webp"是关键判断依据,浏览器只看这个 MIME 类型是否支持,不依赖文件后缀或内容嗅探 -
<img>必须作为<picture>的最后一个子元素,且不能省略;它是所有不支持<picture>或不识别该type的兜底 - 不要把 WebP 放在
<img src>里再指望“自动兼容”——IE、旧 Safari、部分安卓 WebView 都会直接挂掉
为什么 Chrome 显示正常但 Safari 还是加载 PNG
Safari 从 14.0(macOS)和 14.5(iOS)才开始支持 WebP,旧版本即使加了 <source type="image/webp"> 也会跳过,直接走 <img>。
- 检查实际用户设备的 Safari 版本:iOS 14.4 及更早、macOS 11.2 及更早均不支持 WebP
- 不要依赖 UA 字符串做 JS 判断再动态插入,
<picture>的解析发生在 HTML 解析阶段,JS 注入太晚,图片请求已发出 - 若需兼容老 Safari,PNG/JPEG 兜底图必须存在且尺寸一致,否则 layout shift 明显
Webpack/Vite 构建时 WebP 没生成或路径错乱
构建工具默认不处理 WebP,即使你写了 .webp 文件,打包后路径可能丢失、public 目录未复制、或 loader 没配 type 声明。
立即学习“前端免费学习笔记(深入)”;
- Vite 用户:确保
public/下的.webp文件被原样拷贝,但引用时仍要用<source srcset="/logo.webp">(注意开头斜杠) - Webpack 用户:需添加
url-loader或asset-module并显式配置type: "asset",否则require("./logo.webp")会报错 - Next.js 用户:
next/image自动处理 WebP,但仅限src属性;<source>仍需手动写,且unoptimized: true下不会转 WebP
WebP 在 <img> 里直接用有没有例外场景
有,但极窄:仅限你能 100% 确认目标环境支持 WebP,比如企业内网统一 Chrome 90+、或 PWA 安装后通过 beforeinstallprompt 检测并限制入口。
- CDN 或通用网站严禁这么用——哪怕数据说“98% 支持”,剩下 2% 的用户看到空白图就是 100% 的体验失败
- HTTP/2 Server Push 或
<link rel="preload">预加载 WebP 时,同样要配合<picture>,否则 preload 的资源可能被丢弃或不触发 - 动画 WebP(APNG 不等价)目前只有 Chrome/Edge 支持,Firefox 和 Safari 完全无视,连 fallback 都不触发,必须避免
WebP 的核心陷阱不在格式本身,而在于开发者误以为「浏览器识别后缀」或「现代浏览器都支持」——实际支持取决于 type 声明 + 渲染引擎能力 + 构建链路完整性,三者缺一不可。



















