ReactJS中如何检测AVIF格式支持 实现可返回布尔值的检测函数
问题根因
你写的isAvifSupported函数始终返回undefined的核心原因是:Image.onload是异步回调事件,函数同步执行到return语句时,图片资源还未完成加载,onload回调还没有触发,returnValue还没有被赋值,自然返回undefined。
解决方案
根据你的使用场景,推荐两种实现方式:
方案1:提前检测+结果缓存(同步使用首选)
在页面初始化阶段提前执行检测,把支持性结果存在全局变量中,后续业务逻辑可以直接同步读取,不需要改动原有调用逻辑:
// 页面加载时就执行检测,缓存支持性结果 let isAvifSupported = false; let isWebpSupported = false; (function detectImageFormatSupport() { // 检测AVIF支持性 const avif = new Image(); avif.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A="; avif.onload = () => isAvifSupported = true; avif.onerror = () => { // 若AVIF不支持,可顺带检测WebP const webp = new Image(); webp.src = "data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA=="; webp.onload = () => isWebpSupported = true; } })();
使用时直接读取缓存变量即可,适配你原本的同步拼接逻辑:
// 注意你原有代码里三元表达式最后一个符号写错了,要把问号改成冒号 let updatedImageUrl = isAvifSupported ? `${imageUrl}?fm=avif` : (isWebpSupported ? `${imageUrl}?fm=webp` : imageUrl);
该方案的优势是检测用的base64图片体积极小,不会带来性能负担,且后续使用是同步逻辑,不用修改原有业务代码结构。
方案2:Promise异步封装(异步场景适用)
如果你的图片URL拼接逻辑本身就是异步执行的,可以用Promise封装检测逻辑,按需调用:
function checkAvifSupport() { return new Promise((resolve) => { const avif = new Image(); avif.onload = () => resolve(true); avif.onerror = () => resolve(false); avif.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A="; }) }
使用方式:
// 异步函数中用async/await调用 async function getOptimizedImageUrl(imageUrl) { const avifSupported = await checkAvifSupport(); return avifSupported ? `${imageUrl}?fm=avif` : imageUrl; } // 或者用then链式调用 checkAvifSupport().then(isSupported => { const updatedImageUrl = isSupported ? `${imageUrl}?fm=avif` : imageUrl; // 后续图片处理逻辑 })
内容的提问来源于stack exchange,提问作者SDK
相关产品推荐
相关产品推荐

