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。结果,即使在网络选项卡中禁用缓存,在我看来浏览器正在加载一个比需要的更大的文件,但这是因为像素比率在以下时间发生了变化:
- devTools 已打开
- 响应模式已启用
您可以在任何给定时间使用简单的 javascript 提醒像素比率来仔细检查:
<script>alert(window.devicePixelRatio)</script>
如果您尝试以多种宽度加载页面进行测试,则可能启用了响应模式,但这也可能会改变像素密度。因此,它可能会像我一样按预期工作。
简单到可笑的答案:
sizes="(max-width: 999px) 50vw, 100vw"
我的目标是提供同一张图片的不同版本 (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。结果,即使在网络选项卡中禁用缓存,在我看来浏览器正在加载一个比需要的更大的文件,但这是因为像素比率在以下时间发生了变化:
- devTools 已打开
- 响应模式已启用
您可以在任何给定时间使用简单的 javascript 提醒像素比率来仔细检查:
<script>alert(window.devicePixelRatio)</script>
如果您尝试以多种宽度加载页面进行测试,则可能启用了响应模式,但这也可能会改变像素密度。因此,它可能会像我一样按预期工作。
简单到可笑的答案:
sizes="(max-width: 999px) 50vw, 100vw"