You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Safari浏览器无法回退AVIF格式图片至兼容格式的问题及解决方案求助

Safari中<picture>标签包含AVIF时无法渲染回退JPG的问题分析与解决

这确实是Safari早期版本处理<picture>标签时的一个已知兼容性问题,算不上严格意义上的Bug,本质是浏览器对未明确指定MIME类型的AVIF资源解析失败后,错误地终止了整个<picture>标签的后续资源匹配流程。

问题根源

Safari在15.4版本才开始原生支持AVIF格式,在此之前的版本完全无法识别AVIF。当你在<picture>中加入不带type属性的AVIF <source>时,Safari会尝试去加载该资源,但因为无法解析,就错误地跳过了后续所有的<source><img>回退项,导致图片完全不显示。而当你删除AVIF的<source>后,浏览器就能正常匹配到JPG资源。

可行的解决办法

这里有几个经过验证的方案,能有效解决这个问题:

  • 给AVIF的<source>明确添加type属性
    这是最直接有效的方法。通过指定type="image/avif",Safari会直接识别出这是自己不支持的格式(旧版本),从而跳过该<source>,继续匹配后续的WebP或JPG资源。修正后的代码如下:

    <picture>
      <source type="image/avif" srcset="https://75tm.gr/GFXS1205/2048/GFXS1205.avif">
      <source type="image/webp" srcset="https://75tm.gr/GFXS1205/2048/GFXS1205.webp">
      <img src="https://75tm.gr/GFXS1205/2048/GFXS1205.jpg" alt="图片描述">
    </picture>
    
  • 检查AVIF资源的编码合规性
    部分非标准编码的AVIF文件会导致Safari(即使是支持AVIF的新版本)解析失败,进而阻塞后续回退逻辑。确保你的AVIF资源是用标准工具(比如libavif、Squoosh)生成的,避免使用有兼容性问题的编码参数。

  • 针对旧版Safari做特性检测(可选)
    如果需要兼容15.4之前的Safari,可以用JavaScript动态判断浏览器是否支持AVIF,再决定是否添加AVIF的<source>标签:

    // 检测AVIF支持
    async function supportsAvif() {
      try {
        const img = new Image();
        await new Promise((resolve, reject) => {
          img.onload = resolve;
          img.onerror = reject;
          img.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=';
        });
        return true;
      } catch (e) {
        return false;
      }
    }
    
    // 动态添加AVIF source
    async function initPicture() {
      const picture = document.querySelector('picture');
      if (await supportsAvif()) {
        const avifSource = document.createElement('source');
        avifSource.type = 'image/avif';
        avifSource.srcset = 'https://75tm.gr/GFXS1205/2048/GFXS1205.avif';
        picture.insertBefore(avifSource, picture.firstChild);
      }
    }
    
    initPicture();
    

    这种方式可以确保旧版Safari不会加载AVIF资源,也不会触发解析阻塞问题。

总结

只要给AVIF的<source>加上type属性,就能让绝大多数Safari版本正常处理回退逻辑,这也是目前业界推广AVIF格式时的标准实践,不需要过度担心兼容性问题。

内容的提问来源于stack exchange,提问作者m.spyratos

火山引擎 最新活动