WebP可减小图片体积25%–35%,需用<picture>实现fallback、srcset精准匹配设备、设置width/height防布局偏移,避免冗余source干扰预加载。

为什么 <picture> 加 srcset 反而变慢?
常见错误是把 <picture> 当成“多图开关”,一股脑塞进一堆 <source>,结果:
- 浏览器必须逐个解析
srcset候选项,哪怕其中 80% 永远不匹配当前设备 - 冗余
source会干扰预加载器(preload scanner),首屏<img>可能晚 1~2 个渲染周期才发起请求 - 没配
sizes属性时,浏览器默认按100vw计算,实际只占 300px 宽的卡片图,却拉下一张 1200w 的 WebP
- 只保留你 CSS 媒体查询真实生效的断点,比如只在
@media (min-width: 768px)和@media (min-width: 1200px)切布局,srcset就只需768w和1200w两档 - 同一
<source>内不要混用w和x单位,部分浏览器直接忽略整条srcset - 用 Chrome DevTools → Network → Disable cache 多刷几次,看哪些
photo.webp请求根本没发出去——那就是该删的冗余项
<img> fallback 必须设 width 和 height
很多人以为 <picture> 包一层就万事大吉,其实最终渲染靠的是内部那个 <img>。如果它没设 width 和 height,或设成 auto,浏览器无法预留空间,图片加载完成前是空白,一渲染就触发 layout shift——用户感觉“闪一下”,这不是网络慢,是渲染阻塞。
- 给
<img>加内联width="800" height="450",数值按原始图比例来,不是响应式尺寸 - 更稳妥用 CSS
aspect-ratio: 16/9,但注意 Safari 15.4+ 才完全支持;老版本得用padding-top技巧降级 - 别指望
object-fit: cover来“修图”,它不改变容器尺寸计算逻辑,该闪还是闪
别用 JS 动态判断格式再插入 <img>
看到“兼容旧浏览器”就想写 JS 判断 supports('image/webp') 再动态 document.createElement('img') 插入——这会彻底破坏预加载器。浏览器在 HTML 解析阶段就该知道要拉哪张图,JS 插入是 DOM 构建完成后的事,首屏图至少晚一个 parse cycle。
- 坚持用原生
<picture>+<source type="image/webp">+<img src="fallback.jpg">结构 - 旧浏览器(如 IE)不识别
type属性,会直接 fallback 到<img>,这是标准行为,不用干预 - 如果真要兼容极老环境(IE8-),用
data-src+ JS 启动懒加载,但那是另一套方案,和<picture>无关
sizes 没写对、width/height 漏掉、或者 srcset 塞了太多永远用不上的尺寸——这些细节不处理,换 AVIF 也白搭。



















