Firefox模拟iPhone X时srcset响应式img的naturalWidth返回值异常问题
问题根因解析
基础API定义澄清
img.naturalWidth的标准行为是返回当前已解码完成的图像资源的固有像素宽度,这个值和元素的CSS显示尺寸、设备像素比(DPR)没有换算关系:只要加载完成的是2000px宽度的原图,这个值就应当返回2000,不会因为是移动端模拟场景就返回375或者经过DPR换算的等效值。img.currentSrc仅返回当前srcset逻辑规则选中的资源URL,不代表这个资源已经完成了完整的加载和解码流程。
场景偏差的具体触发逻辑
你遇到的现象完全来自Firefox在高DPR移动模拟环境下的srcset资源加载实现特性:
- 按照响应式图片的标准选择规则,375px逻辑宽度、DPR=3的场景下,根据
sizes属性计算得到图像显示宽度为100vw即375px逻辑值,乘以DPR后需要的等效像素总宽度为1125px,浏览器会从srcset列表中选中大于该值的2000w资源,这一步的currentSrc返回值是符合规则预期的。 - Firefox为了优化首屏渲染速度,在srcset逻辑选中最终资源后,会先临时加载一张和计算出的显示宽度(375px逻辑宽度)匹配的占位图完成初始渲染,再在后台逐步加载选中的高分辨率原图。
- 你在
window.load事件触发的瞬间读取naturalWidth时,高分辨率的2000w原图还没有完成解码流程,浏览器返回的是临时占位图的固有宽度——也就是刚好375px,而非最终加载完成的2000px原图的宽度。 - 没有配置srcset的第二张测试图,因为跳过了srcset的选择和占位加载流程,会直接全量加载指定的2000w资源,等到load事件触发时已经完成全量解码,所以它的
naturalWidth返回值是正确的2000,和带srcset的图形成了测试中看到的数值差异。
快速验证方式
- 把读取
naturalWidth的代码从window.load回调中移出,改成延迟1~2秒后再执行读取操作,你会发现带srcset的图的naturalWidth会自动从375更新为正确的2000。 - 同场景下在Chrome、Safari中测试不会出现这个提前返回占位图尺寸的偏差,属于Firefox独有的实现差异。
内容的提问来源于stack exchange,提问作者Mohamed Ramrami
相关产品推荐
相关产品推荐

