今天我们将讨论 Web 响应式图像,这是一个非常流行的话题,而且非常有问题。

如果你搜索这个主题,你会发现无数的文章有各种各样的解释,但我不会重复这些,并以不同的方式教你。

正确加载图像,提高您的 SEO 排名并为您的网站提供更好的用户体验。

什么是响应式图像?

响应式图像将(应该)自动调整以适应屏幕尺寸。 但是……这是正确的做法吗? 嗯,是的,也不是。 如果您对此进行谷歌搜索或查看诸如 Bootstrap 之类的现代框架,您会注意到它们对“响应式图像”的定义是一个简单的 CSS,类似于:

1max-width:  100%;
2height:  auto;

虽然这“有效”,但并不完全正确。有几个原因,但最重要的一个是图像大小。我不是在谈论图像的“宽度/高度”,而是在谈论以千字节/兆字节为单位的实际图像大小。

大多数网站(就像这些年来我见过的 80% 的网站一样)在他们的网站上使用非常大的图像,然后简单地“缩放”它们。这样的图像通常从 1000px 到 4000px,我什至看到了 8000px ! (这有多疯狂)。

这些图像的大小往往非常大,从 1 MB 到 10 甚至 20 MB。我很少看到人们在导出图像时会压缩图像。话虽如此,想象一下,当您有一个包含 5、10、20 或更多图像的图像重的网站并且用户在移动设备上访问您的网站时。即使在 5G 上,也需要为图像下载大量数据,更不用说其余的了。

如何创建响应式图像?

浏览器在图像源集(srcset)的支持方面提供帮助。使用此功能,我们可以有效地拥有不同尺寸的图像的多个版本,浏览器将根据屏幕尺寸选择正确的版本。现在这是响应式的!

然而,由于多种原因,大多数人无法处理图像源集,从“我不知道”到“我不明白”等等。

随着技术的发展,我们现在可以使用在线工具和 API 为我们自动创建这些源集。但是请记住,自动创建这些并不意味着您可以简单地复制粘贴结果并期望它正常工作。

从我所做的所有工作和测试来看,没有“一刀切”的解决方案,您总是需要做一些额外的工作。

选择正确的图像 HTML 标签

这是您必须了解的第一件事,也是最重要的事情。您可以使用传统的 <img /> 或现代的 <picture> 标签。

每个人都有自己的陷阱,但根据我自己的经验,<picture> 总是赢。这个标签被浏览器广泛支持,所以这不应该是一个问题。

没有自动方法可以为动态网站生成正确的尺寸(据我所知)。以众所周知的 WordPress 为例,它会根据您上传的图片和放置的位置生成不规则和错误的大小。

使用 img 标签

img 标签在大多数网站上; 对于响应式图像,<img /> 标签与 srcset 属性相结合,但我可以自信地告诉你,它们都不能正常工作。

问题之一是 <img /> 标签在某些浏览器(例如 Chrome)上无法正常运行。 我实际上有一个问题打开stackoverflow.com 关于这个没有解释为什么。

另一个问题是正确设置sizes属性是一件很痛苦的事情。 有很多文章的解释非常生硬和不完整,坦率地说,我觉得非常沮丧。

话虽如此,我不会讨论使用 <img /> 来处理响应式图像,因为它毫无意义(在我看来)。

使用图片标签

picture 我认为标签是最好的,它允许我们操纵和指示浏览器加载我们想要的图像。

它还支持许多其他功能,例如指定艺术方向、替代图像格式等。 有了这套不错的能力,我们就可以实现我们的目标。

没问题,是时候让这个浏览器 今年死 .

生成响应式图片尺寸

如上所述,我们可以使用许多在线工具来调整大小并为我们生成正确的图像和源代码,只需点击几下。

我建议你使用这个: https://responsivebreakpoints.com/ 作为起点。 该工具将调整您的图像大小并生成断点以具有响应图像。

例如他们网站上的狗图片,将有几个不同的图像调整大小和它们各自的 HTML 代码:

 1<picture>
 2	<source
 3		media="(max-width: 767px)"
 4		sizes="(max-width: 1534px) 100vw, 1534px"
 5		srcset="
 6		dog_ar_1_1,c_fill,g_auto__c_scale,w_200.jpg 200w,
 7		dog_ar_1_1,c_fill,g_auto__c_scale,w_493.jpg 493w,
 8		dog_ar_1_1,c_fill,g_auto__c_scale,w_707.jpg 707w,
 9		dog_ar_1_1,c_fill,g_auto__c_scale,w_877.jpg 877w,
10		dog_ar_1_1,c_fill,g_auto__c_scale,w_1032.jpg 1032w,
11		dog_ar_1_1,c_fill,g_auto__c_scale,w_1108.jpg 1108w,
12		dog_ar_1_1,c_fill,g_auto__c_scale,w_1259.jpg 1259w,
13		dog_ar_1_1,c_fill,g_auto__c_scale,w_1353.jpg 1353w,
14		dog_ar_1_1,c_fill,g_auto__c_scale,w_1468.jpg 1468w,
15		dog_ar_1_1,c_fill,g_auto__c_scale,w_1534.jpg 1534w">
16	<source
17		media="(min-width: 768px) and (max-width: 991px)"
18		sizes="(max-width: 1983px) 70vw, 1388px"
19		srcset="
20		dog_ar_4_3,c_fill,g_auto__c_scale,w_538.jpg 538w,
21		dog_ar_4_3,c_fill,g_auto__c_scale,w_793.jpg 793w,
22		dog_ar_4_3,c_fill,g_auto__c_scale,w_1004.jpg 1004w,
23		dog_ar_4_3,c_fill,g_auto__c_scale,w_1198.jpg 1198w,
24		dog_ar_4_3,c_fill,g_auto__c_scale,w_1238.jpg 1238w,
25		dog_ar_4_3,c_fill,g_auto__c_scale,w_1384.jpg 1384w,
26		dog_ar_4_3,c_fill,g_auto__c_scale,w_1388.jpg 1388w">
27	<source
28		media="(min-width: 992px) and (max-width: 1199px)"
29		sizes="(max-width: 2400px) 60vw, 1440px"
30		srcset="
31		dog_ar_16_9,c_fill,g_auto__c_scale,w_596.jpg 596w,
32		dog_ar_16_9,c_fill,g_auto__c_scale,w_877.jpg 877w,
33		dog_ar_16_9,c_fill,g_auto__c_scale,w_1086.jpg 1086w,
34		dog_ar_16_9,c_fill,g_auto__c_scale,w_1314.jpg 1314w,
35		dog_ar_16_9,c_fill,g_auto__c_scale,w_1440.jpg 1440w">
36	<img
37		sizes="(max-width: 7000px) 40vw, 2800px"
38		srcset="
39		dog_c_scale,w_480.jpg 480w,
40		dog_c_scale,w_713.jpg 713w,
41		dog_c_scale,w_1036.jpg 1036w,
42		dog_c_scale,w_1180.jpg 1180w,
43		dog_c_scale,w_1313.jpg 1313w,
44		dog_c_scale,w_1433.jpg 1433w,
45		dog_c_scale,w_1606.jpg 1606w,
46		dog_c_scale,w_1748.jpg 1748w,
47		dog_c_scale,w_1884.jpg 1884w,
48		dog_c_scale,w_2015.jpg 2015w,
49		dog_c_scale,w_2133.jpg 2133w,
50		dog_c_scale,w_2260.jpg 2260w,
51		dog_c_scale,w_2377.jpg 2377w,
52		dog_c_scale,w_2345.jpg 2345w,
53		dog_c_scale,w_1871.jpg 1871w,
54		dog_c_scale,w_2800.jpg 2800w"
55		src="dog_c_scale,w_2800.jpg"
56		alt="">
57</picture>

注意它为我们覆盖了多少屏幕尺寸,很酷吧? 但是将其复制粘贴到您的网站是否足够好? 不。

这些图像源集的最大问题是 sizesmedia 属性。 理解起来非常复杂,使其正常工作更加复杂。

话虽如此,您需要做的是使代码更短且更易于理解。 在我的网站(您正在阅读的那个)上,我使用了 Bootstrap 提供的通用响应式断点并创建了我自己的集合。

自己创建响应式图像尺寸

最好的(坦率地说,唯一的解决方案)是自己创建图像标签。

当您从头开始开发定制网站时,这对您非常有利,但是当您使用 WordPress 之类的东西时,那就是另一回事了,将会有另一篇关于此的文章。

作为一个起点,我需要一种清晰而简单的方法来理解设备断点; 所以我使用了 Bootstrap 提供的非常可靠的:

断点设备方面
X-小小型设备(人像手机,小于 576 像素)<576px
小的小型设备(横向手机,576px 及以上)≥576px
中等的中型设备(平板电脑,768 像素及以上)≥768px
大的大型设备(台式机,992 像素及以上)≥992px
特大号大型设备(大型桌面,1200 像素及以上)≥1200px
特大号大型设备(更大的桌面,1400 像素及以上)≥1400px

通过以上内容,我创建了我的“自己的”图像源集,根据上述设备尺寸加载适当的图像:

1<picture>
2	<source srcset="" media="(min-width: 1400px)">
3	<source srcset="" media="(min-width: 1200px)">
4	<source srcset="" media="(min-width: 992px)">
5	<source srcset="" media="(min-width: 768px)">
6	<source srcset="" media="(min-width: 576px)">
7	<source srcset="" media="(min-width: 320px)">
8	<img src="" width="" height="" class="" alt="" >
9</picture>

这让我对应该发生什么以及如何发生有一个清晰的认识和理解。 换句话说,我知道每个设备上应该加载什么图像并且它会这样做。

虽然这似乎可以使用,但它还没有完全准备好。 在特定设备上加载这些图像还不够好,因为图像可能仍然太大。

示例 1

  • 在大型设备(大型桌面,1200 像素及以上)上,您嵌入图像集的容器的固定大小为 800 像素
  • 浏览器将查看您的视口,例如 1920 像素,它将加载 1400 像素大小的图像(实际上您需要 768 像素大小的图像……)

示例 2

  • 在任何设备上,您嵌入图像集的容器是 400 像素的固定大小(例如,可以是卡片或简单的盒子)
  • 浏览器将查看您的视口,例如 1920 像素,它将加载 1400 像素大小的图像(实际上您需要 320 像素的图像大小……)

话虽如此,您正在加载错误的图像,这会让您和您的用户付出代价。 首先,您会降低速度(顺便会影响您的 SEO 排名),然后如果用户使用移动设备或带宽较慢,则您的用户将永远等待图像加载。

正确的解决方案是调查您嵌入图像的容器并确定合适的大小。

您可以通过检查页面并模拟不同的设备来非常轻松地做到这一点,通常容器或多或少保持相同。

因此,对于上述示例 1,我已将代码修改如下:

1<picture>
2	<source srcset="" media="(min-width: 1200px), (min-width: 1400px), (min-width: 2500px)">
3	<source srcset="" media="(min-width: 992px)">
4	<source srcset="" media="(min-width: 768px)">
5	<source srcset="" media="(min-width: 576px)">
6	<source srcset="" media="(min-width: 320px)">
7	<img src="" width="" height="" class="" alt="">
8</picture>

这是什么意思? 这很不言自明,但无论如何我都会解释:

  • 在最小宽度 320px 的设备上,加载 320px 的图像
  • 在最小宽度 576px 的设备上,加载 576px 的图像
  • 在最小宽度 768px 的设备上,加载 768px 的图像
  • 在最小宽度 992px 的设备上,加载 992px 的图像
  • 在最小宽度 1200px 或 1400px 或 2500px 的设备上加载 1200px 图像

最后一行确保当容器大小仅为 800 像素(或在我的情况下单击展开文章时为 1200 像素)时浏览器不会加载更大的图像大小

我发现以上在加载正确的图像尺寸方面几乎是完美的。 甚至 Google Pagespeed 也喜欢它并且不会产生任何警告,因为我们正在加载正确的图像尺寸。

测试你的响应式图片

我很确定在阅读完上述内容后,您对如何测试您的图像是否正确加载有一个大致的了解,但是我仍然会解释。

如果您有许多图像,测试过程可能会令人生畏,但值得付出努力。

您需要做的很简单,只需要一些时间:

  • 打开您想要的浏览器并加载您的页面
  • 打开开发人员工具并转到网络选项卡并仅选择“图像”过滤器
  • 在多个设备(移动设备、平板电脑等)上刷新您的页面并查看加载了哪些图像

就是这样,没有什么花哨的。

### 技巧和窍门

  • 如果您有很多图像(不止一个标题),请使用 loading=lazy 属性。 你可以阅读更多关于它 这里 .
  • 如果您无法自己导出图像/调整它们的大小,您可以使用在线服务来执行此操作。 他们还将提供 CDN,可以快速加载您的图像。 我建议你使用 Cloudflare Images .
  • 正确命名您的图像,这非常重要。 如果您没有正确命名您的图像(例如 image-small.jpg 或 image-320.jpg),那么您在测试时将无法轻松确定正在加载的图像。

好了,就是这样,希望这篇文章对你有所帮助。