srcset - 响应图像加载错误的文件

srcset - Responsive image loading wrong file

我的目标是提供同一张图片的不同版本 (resolutions/sizes),它应该占据视口宽度的 100%,这样我就可以为移动设备提供 800 像素的版本(或者,通常,显示器较小或连接速度较慢的设备),1366 像素及以上到较大的桌面显示器。

问题是我正在使用 Chromium 设备模拟器对其进行测试,一些小屏幕设备加载 1366px 版本而不是 800px:iPhone 6/7/8(375px 宽度)加载800px 图片,但是 iPad (768px)、Nexus 5 (360px) 和 iPhoneX (375px) 都加载 1366px 而不是加载 800px。

我不太确定是否正确理解了 sizes 指令,这是我的代码,默认 src 引用 2880px 版本只是为了帮助测试:

<img class="img-fluid" 
    srcset="img/dreamstime_800w_109635242.jpg 800w,
         img/dreamstime_1366w_109635242.jpg 1366w,
         img/dreamstime_2880w_109635242.jpg 2880w"
    sizes="(max-width: 800px) 100vw,
        (max-width: 1366px) 100vw,                      
        2880px 100vw"
    src="img/dreamstime_2880w_109635242.jpg"/>

这与视网膜显示器(我认为还有它们的 DPI)有关。

据我所知,Retina 显示器会选择其显示器宽度两倍或三倍的第一张图像,具体取决于它们各自的 Retina 显示器(2x、3x 等)。

另一个简单的解决方案是清除浏览器缓存。如果您最大和最糟糕的图像已经被缓存,Chrome(例如)将始终加载该图像。

您的 sizes 属性告诉浏览器图像始终以全视口宽度显示,因此您只需将其替换为 sizes="100vw"

因此浏览器采用当前视口宽度,将其乘以屏幕密度,并为其提供所需图像的宽度。然后它从 srcset.

中的列表中获取最接近的图像

你不能用它来“为移动设备提供 800px 的版本”,因为现在大多数移动设备的密度都比桌面设备大,你不能用 <img srcset… sizes…> 来阻止它。

如果您真的想忽略屏幕密度(出于什么原因?)并且:

  • 为小型设备提供最小的图像,
  • 向中型设备提供中型图像
  • 为大型设备提供大图像
  • 保留最大的图像作为后备

然后你必须使用 <picture> 和这样的媒体查询:

html <picture> <source media="(max-width: 800px)" srcset="img/dreamstime_800w_109635242.jpg 800w"> <source media="(max-width: 1366px)" srcset="img/dreamstime_1366w_109635242.jpg 1366w"> <img src="img/dreamstime_2880w_109635242.jpg"> </picture>

对于未来的读者 - 我很难理解为什么 srcset 完全无视我的尝试。经过几个小时的沮丧和愤怒之后,我找到了世界上最明显的答案——我正在使用 Retina Macbook Pro,但我没有触发像素密度。

我改成了

<img class="<?= $image_class;?>" data-caption="<?php echo $image['alt']; ?>"
data-src="<?php echo $image['sizes']['medium']; ?>"
data-srcset="<?php echo $image['sizes']['medium']; ?> 600w 2x, 
<?php echo $image['sizes']['large']; ?> 1280w 2x"
sizes="(min-width: 150px) 600px, 100vw"
width="150" height="150"
alt="<?php echo $image['alt']; ?>">

一切正常 - 至少我可以弄清楚发生了什么事。 呸。 大家圣诞快乐!

使用 Chrome 模拟器测试我的网页时,我有时发现(就像您一样)加载的图像显然比需要的大,尤其是在小型移动设备上。我终于意识到这不是我的错误,而是 Chrome 从缓存中拉出一张更大的图片(如果那里恰好有一张图片的话)。单击模拟器中的复选框以在测试时禁用缓存,问题消失了,我期望看到加载的大小实际上已加载。

我注意到当 chrome devTools 打开并启用响应模式时,我的设备像素比从 1 变为 2。结果,即使在网络选项卡中禁用缓存,在我看来浏览器正在加载一个比需要的更大的文件,但这是因为像素比率在以下时间发生了变化:

  1. devTools 已打开
  2. 响应模式已启用

您可以在任何给定时间使用简单的 javascript 提醒像素比率来仔细检查:

<script>alert(window.devicePixelRatio)</script>

如果您尝试以多种宽度加载页面进行测试,则可能启用了响应模式,但这也可能会改变像素密度。因此,它可能会像我一样按预期工作。

简单到可笑的答案:

sizes="(max-width: 999px) 50vw, 100vw"