详细的聊一聊如何使用响应式图片,提升网页加载速度

news2024/11/27 1:39:08

1c6ca30602562d80aabaf700d8e3a19a.jpeg

开篇

确保图片在所有屏幕尺寸上都能良好显示是一项困难的任务,因为你需要考虑图片的大小、图片的放置位置、显示图片的比例、用户连接的速度等等众多因素。结果是,大多数开发者只会为所有屏幕尺寸使用同一张图片,并让浏览器调整图片的大小以适应屏幕。这是一种不好的做法,因为浏览器仍会下载完整尺寸的图片(通常非常大),即使它只以其一部分尺寸显示。这会浪费用户的带宽,并且会显著减慢页面加载速度(尤其是在较慢的连接下)。

解决这个问题的方法是使用响应式图片。响应式图片是根据用户的屏幕尺寸进行优化的图片。这意味着图片将以适合用户设备的正确尺寸和质量进行下载。这将显著减少传输给用户的数据量,加快页面加载速度。有许多实现响应式图片的方法,从简单到复杂。在本文中,我将向您展示如何在您的网站上呈现响应式图片的所有方式。

img srcset 属性

到目前为止,实现响应式图片最简单的方法是在img标签上使用srcset属性。该属性允许您定义多个不同尺寸的图片,然后浏览器将自动选择最适合用户屏幕尺寸的图片。

<img
  src="tree-1200.jpg"
  alt="A tree"
  srcset="tree-400.jpg 400w, tree-800.jpg 800w, tree-1200.jpg 1200w"
/>

这段代码可能看起来有些混乱,所以让我详细解释一下其中发生的事情。首先,我们有了您已经熟悉的普通src和alt属性,它们与所有图片一样。在极少数情况下,如果用户使用的浏览器不支持srcset,那么将使用src URL来显示图片。不过,这种情况非常罕见,因为srcset在所有主要浏览器中已经支持了5-10年。

让人困惑的是srcset属性。该属性接受一个逗号分隔的图片URL和它们的宽度列表。如果我们看一下列表中的第一项tree-400.jpg 400w,可以看到URL是tree-400.jpg。这个URL的名称并不重要,但通常当您在不同尺寸上有多个相同的图片时,您会希望在名称中加上尺寸信息。

这项内容的第二部分是400w。这可能会让人困惑,因为w不是CSS单位,实际上w代表图像的实际宽度,以像素为单位。您可以通过在文件浏览器/资源管理器中检查图像来轻松找到这个宽度。如果您使用的是Windows操作系统,可以右键单击图像,选择属性,而在Mac上应该有一个名为"获取信息"的选项。在本例中,图像的宽度为400像素,因此我们将宽度设置为400w。

浏览器将使用这些信息来自动确定要下载的图片。例如,如果用户的屏幕宽度小于400像素,它将使用tree-400.jpg图像,因为这是可以在不进行任何拉伸/模糊像素的情况下使用的最小图像。一旦浏览器的宽度大于400像素,浏览器将切换到使用tree-800.jpg图像。这是因为400像素的图像现在比当前屏幕尺寸小,如果使用它会被拉伸/模糊。对于所有屏幕尺寸,这个过程会一直持续,直到浏览器达到列表中最大的图像。

这很棒,因为现在在小屏幕上,浏览器将下载一个较小的图像,而大屏幕仍将获得高分辨率的图像。这将显著减少传输给用户的数据量,并加快页面加载速度。下面是一个示例,展示了这种情况。尝试将浏览器大小调整为较小的尺寸,然后重新加载页面,您将看到下载了较小的图像。

<img
  style="width: 100%; border-radius: 1rem;"
  src="https://placehold.co/3200x800/png"
  srcset="
    https://placehold.co/800x200/png   800w,
    https://placehold.co/1600x400/png 1600w,
    https://placehold.co/3200x800/png 3200w
  "
/>

280a8b59cb3682108101f7693e593506.png

在进行测试时,您可能会注意到下载的图像实际上比您预期的要大。例如,如果您的屏幕宽度为700像素,您的浏览器可能仍会下载1600像素宽的图像,而不是800像素宽的图像。这是因为浏览器还考虑了您设备的像素密度。如果您使用的是高分辨率设备或浏览器缩放级别较高,浏览器将下载一个较大的图像,以确保在您的屏幕上显示良好,因为每个CSS像素实际上对应屏幕上的多个像素。要检查设备的像素密度,您可以在控制台中使用window.devicePixelRatio。

如何处理不同的像素密度

有时候,您可能有一张图像在屏幕上始终保持相同的尺寸,但您希望它在高分辨率设备上看起来很好。例如,如果您的标志始终为100像素宽,在只提供100像素宽图像的情况下,在高分辨率设备上会显得模糊不清。为了解决这个问题,您可以使用srcset属性,通过使用x单位来表示像素密度来提供多个不同尺寸的图像。

<img
  src="logo-200.jpg"
  alt="Our Logo"
  srcset="logo-100.jpg 1x, logo-150.jpg 1.5x, logo-200.jpg 2x"
/>

上述代码与我们之前的srcset示例非常相似,但主要区别在于我们使用了类似1.5x和2x的单位,而不是硬编码的像素值。这些单位指的是屏幕的像素密度。例如,如果某人的屏幕具有每个CSS像素1.25个设备像素的像素密度,则将使用logo-150.jpg图像,因为这是可以在不拉伸/模糊像素的情况下使用的最小图像。

您无需包含1x单位,因为它是默认值。如果您只有两个图像,您可以使用logo-100.jpg,logo-200.jpg 2x,而不是logo-100.jpg 1x,logo-200.jpg 2x。

img sizes 属性

到目前为止,我们介绍的是实现响应式图片的最基本方法,但在许多情况下,您的图像尺寸实际上并不等于屏幕的宽度。本博客就是一个很好的例子。在小屏幕上,我的博客内容(包括图像)占据了整个屏幕的宽度,但在较大屏幕上,我将内容居中显示,并设置了一个有限的最大宽度。如果我们仅使用像上面那样的srcset,我们的图像将根据浏览器窗口的完整尺寸进行缩放,这将导致在大屏幕上图像比实际需要的要大。这就是sizes属性的用途。

sizes属性允许您定义图像的单个尺寸,例如50vw,或者一组媒体查询,用于确定图像应该使用的尺寸。默认情况下,如果您没有将sizes属性添加到img标签中,它会假定尺寸为100vw,这就是为什么上面的图像根据浏览器窗口的完整宽度进行缩放。让我们看一下如何使用sizes属性来考虑具有最大尺寸的博客这样的情况。

<img
  src="tree-1200.jpg"
  alt="A tree"
  srcset="tree-400.jpg 400w, tree-800.jpg 800w, tree-1200.jpg 1200w"
  sizes="(max-width: 800px) 100vw, 800px"
/>

上面的代码与之前的代码完全相同,只是我们添加了sizes属性。sizes属性接受一个以逗号分隔的媒体查询和尺寸列表。为了理解其中的内容,让我们逐个解析列表中的每个项。

我们的第一个项(max-width: 800px)100vw 有两个部分。第一部分是我们要检查的媒体查询。在这种情况下,我们要检查屏幕宽度是否小于800像素。第二部分是如果媒体查询为true时我们要使用的尺寸。在这种情况下,我们使用100vw,这意味着我们希望浏览器根据浏览器窗口的完整宽度选择图像尺寸。

第二个项800px没有媒体查询,而只是一个尺寸。这被视为我们的回退尺寸。如果之前定义的所有媒体查询都为false,那么它将使用这个回退尺寸。从本质上讲,您可以将其视为始终为true的媒体查询。我们通过这个项表达的意思是,假设我们的图像在屏幕上占据了800像素,我们应该选择我们的图像。然后,浏览器将使用这个尺寸来确定要下载的图像。如果您的浏览器具有高分辨率或您在页面上进行了缩放,它可能会下载比800像素更大的图像,但通常情况下,这是确保图像不会过大的一种好方法。

将这两个项组合起来,基本上是在说我们的图像应该根据浏览器的宽度选择,在800像素之前。在那一点上,图像在我们的屏幕上永远不会占用超过800像素的空间,所以我们应该根据这个800像素的尺寸来调整我们的图像尺寸。这是我为这个博客添加响应式图像的代码方式,因为我的博客在较大的屏幕尺寸上受到最大宽度的限制。让我们看一个实际的示例。

<img
  style="width: 100%; border-radius: 1rem;"
  src="https://placehold.co/3200x800/png"
  srcset="
    https://placehold.co/400x100/png   400w,
    https://placehold.co/800x200/png   800w,
    https://placehold.co/1200x300/png 1200w,
    https://placehold.co/1600x400/png 1600w,
    https://placehold.co/3200x800/png 3200w
  "
  sizes="(max-width: 800px) 100vw, 800px"
/>

286f91a7e6cfec6fe487d551eda23748.png

我添加了许多不同的图像尺寸,这样您就可以看到它们如何与不同的像素密度配合工作。如果您使用的是高分辨率设备,您可能会注意到浏览器下载了比800像素更大的图像。您还可以通过缩放设备来模拟此过程,因为您的设备缩放得越多,像素密度就越高,如果您缩放足够多,浏览器将需要下载更高分辨率的图像,以确保在屏幕上显示良好。

潜在的陷阱

sizes属性非常强大,但在使用它时需要注意以下几点。

顺序很重要

如果您的sizes属性中有多个媒体查询,将选择第一个为true的媒体查询对应的图像。这意味着您的媒体查询的顺序很重要。

<img
  src="https://placehold.co/3200x800/png"
  srcset="
    https://placehold.co/400x100/png 400w,
    https://placehold.co/800x200/png 800w
  "
  sizes="(max-width: 800px) 100vw, (max-width: 500px) 50vw, 1200px"
/>

如果您按照上述的方式编写sizes属性,那么您的代码将无法按预期工作。原因是第一个媒体查询(max-width: 800px)100vw 在所有小于800像素的屏幕尺寸下都为真。这意味着第二个媒体查询(max-width: 500px)50vw 将永远不会被使用,因为只有在屏幕小于500像素时才为真,而在这些尺寸范围内第一个媒体查询将始终为真,因此它将始终被优先选择。为了解决这个问题,您需要重新排序媒体查询,使最具体的媒体查询排在最前面,最不具体的媒体查询排在最后。

<img
  src="https://placehold.co/3200x800/png"
  srcset="
    https://placehold.co/400x100/png 400w,
    https://placehold.co/800x200/png 800w
  "
  sizes="(max-width: 500px) 50vw, (max-width: 800px) 100vw, 1200px"
/>

同样重要的是,确保您的默认尺寸(即没有媒体查询的尺寸)始终放在最后,因为它总是为真,所以如果它排在最前面,它将始终被选择,而不考虑其他媒体查询。

使用百分比

到目前为止,我已经向您展示了如何使用像px这样的具体尺寸,以及如何使用基于浏览器窗口的尺寸,比如vw,但是百分比尺寸(如50%)该怎么办呢?不幸的是,在sizes属性中不支持百分比尺寸。原因是浏览器在不知道父元素的宽度之前,无法确定百分比定义的内容的宽度。这意味着浏览器必须等到整个页面加载完成后才能确定要下载哪个图像。这将是一个糟糕的用户体验,因为用户必须等到整个页面加载完成才能看到任何图像。

picture 元素

到目前为止,我们主要讨论了如何以不同尺寸渲染相同的图像,以帮助提高加载时间,但这并没有涵盖在不同屏幕尺寸下显示不同图像的情况。例如,如果您的页面有一个宽度跨越整个页面的大标题,您可能希望在移动设备和桌面设备上显示不同的图像,因为您可以在桌面设备上使用更多细节的图像。这就是picture元素的用途。

picture元素允许您定义多个source元素,用于在不同的屏幕尺寸下定义要使用的不同图像。然后,浏览器将选择与当前屏幕尺寸匹配的第一个source元素,并使用该图像。如果没有任何source元素与当前屏幕尺寸匹配,则将使用picture元素中定义的img作为备用图像。

<picture>
  <source media="(max-width: 500px)" srcset="hiking-narrow.jpg" />
  <img src="hiking-wide.jpg" alt="Someone jumping on a hike" />
</picture>

e6391fb21fed20b6e540ca1ec64589d0.jpeg

如果你调整浏览器的大小,你应该会看到图像在两个不同版本之间变化。如果你使用的是移动设备,你可能需要缩放来观察图像的变化。我们为较小的屏幕尺寸提供了更裁剪的图像版本,因为在较小的屏幕上,图像的焦点——人物——会变得太小。

现在让我们看一下实际的代码,了解它是如何工作的。为了让picture元素起作用,你至少需要将一个普通的img标签放在picture元素的最后。

<picture>
  <img src="hiking-wide.jpg" alt="Someone jumping on a hike" />
</picture>

这样做将只是像普通的img标签一样渲染图像。在这里,更加高级的是使用source元素。除了默认版本之外,每个图像的变体都应该有自己的source元素。在我们的例子中,我们只有一个source元素,但您可以根据需要添加任意数量的source元素。

<picture>
  <source media="(max-width: 500px)" srcset="hiking-narrow.jpg" />
  <source media="(max-width: 1000px)" srcset="hiking-medium.jpg" />
  <img src="hiking-wide.jpg" alt="Someone jumping on a hike" />
</picture>

在每个source元素内部,您有两个主要属性。srcset属性的工作方式与img标签的srcset属性相同。这意味着,如果我们有hiking-narrow.jpg图像的多个分辨率,我们可以将它们包含在srcset属性中。不过,在使用picture元素时,每个source元素通常只有一个分辨率,因此您可以将其作为srcset属性中的唯一URL。

另一个属性是media属性。它的工作方式类似于sizes属性中的媒体查询,但是在source元素的media属性中,您只能定义一个媒体查询。这些查询与sizes属性一样,从上到下逐个检查,只有第一个匹配的媒体查询会被使用。如果没有任何媒体查询匹配,则使用img标签作为备选项,这也是为什么我们没有针对较大屏幕尺寸专门设置source元素的原因。

为什么要使用picture元素而不是其他替代方案

对于picture元素的一个大误解是,为什么要使用它而不是img元素的sizes属性或CSS。

为什么 sizes 不适合

sizes属性不适合此任务的主要原因是,picture元素始终会切换到与当前屏幕尺寸匹配的source元素中定义的图像。这意味着,如果您通过缩放或调整窗口大小来更改屏幕尺寸,它将切换到正确的图像。

sizes属性的工作方式类似,但只适用于增大屏幕尺寸的情况。如果您的屏幕尺寸缩小,浏览器将不会切换或下载较小的图像,因为它已经有了较大的图像,因此将继续渲染该图像。这非常好,因为它可以节省带宽,因为当您已经拥有较大的图像时,下载较小的图像没有意义。但是,当您希望在不同的屏幕尺寸上显示不同的图像时,这可能会成为一个问题,这就是为什么picture元素是理想的选择。

为什么 CSS 不适合

如果您熟悉CSS,您可能会意识到我们可以通过使用一些简单的CSS属性来实现非常类似的效果。

img {
  object-fit: cover;
  object-position: center;
}

这样做将使图像填充父元素的整个宽度,然后裁剪图像,以确保图像的中心始终可见。这将给我们非常相似的效果,但缺点是即使在小屏幕尺寸下我们只显示图像的一部分,仍然需要下载完整分辨率的图像。这与我们使用响应式图像所要实现的目标背道而驰。

结论

响应式图像可能看起来是一个复杂的话题,但实际上并不需要如此。实现基本的响应式图像只需在img标签中添加srcset属性,然后让浏览器完成其余工作。如果您想进一步深入,您可以使用sizes属性来帮助浏览器选择正确的图像,或者如果您想在不同的屏幕尺寸上显示不同的图像,可以使用picture元素。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。

原文:
https://blog.webdevsimplified.com/2023-05/responsive-images/

非直接翻译,有自行改编和添加部分,翻译水平有限,难免有疏漏,欢迎指正

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/662438.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SCI征稿】仅1个月22天录用,极速录用见刊,可接受智能交通,自动驾驶汽车,新型智能算法,智能交通系统,安全运输,交通拥堵等领域

智能算法类SCIE&EI ◆ 影响因子&#xff1a;4.0-5.0 ◆ 期刊分区&#xff1a;JCR2区&#xff0c;中科院3区 ◆ 检索情况&#xff1a;SCIE&EI 双检&#xff0c;正刊 ◆ 征稿领域&#xff1a;智能算法在智能交通中的应用&#xff0c;包括自动驾驶汽车、新型智能算法、…

20个ArcGIS Pro 提示和技巧

ArcGIS Pro是最通用的GIS软件在当今的行业中。为了帮助你充分利用ArcGIS Pro&#xff0c;我们整理了一份20个提示和技巧。 这些技巧包括从基本的定制选项到高级地理空间分析和数据可视化技巧。 链接地图视图 在ArcGIS Pro中链接视图有助于同步显示一个项目中的多个地图或场景…

java项目之汉服文化平台网站(ssm+vue)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的汉服文化平台网站。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&…

2017年全国硕士研究生入学统一考试管理类专业学位联考写作试题

2017年1月真题 四、写作&#xff1a;第56~57小题&#xff0c;共65 分。其中论证有效性分析30 分&#xff0c;论说文35分。 56、论证有效性分析&#xff1a; 分析下述论证中存在的缺陷和漏洞&#xff0c;选择若干要点&#xff0c;写一篇600字左右的文章&#xff0c;对论证的有…

GPT提示词系统学习-第二课-使用GPT帮你“填表格”

开篇 前面我们说到了GPT的提示词使用的好不好对你可以得到精准的答案是至关重要的。今天我们来看看,GPT中如何使用提示词来帮助我们填一个表格。 参照样本让GPT制作可填表格 请阅读以下销售邮件。删除任何可用于识别个人身份的信息 (PII),并用相应的占位符替换它。 例如,…

BIO-NIO-AIO案例

BIO-NIO-AIO案例 1、BIO编程 BIO 有的称之为 basic(基本) IO,有的称之为 block(阻塞) IO&#xff0c;主要应用于文件 IO 和网络 IO&#xff0c; 这里不再说文件 IO, 大家对此都非常熟悉&#xff0c;本次课程主要讲解网络 IO。 在 JDK1.4 之前&#xff0c;我们建立网络连接的时…

endnotex9 在word中插入参考文献遇到的问题

添加超链接 在EndNote X9中点击如下按钮 勾选如图所示选项后确认即可 找到插入文献的上标&#xff0c;按住“Ctrl”后鼠标点击即可跳转到对应文献 修改文献添加位置 先使用endnote插入一篇文献&#xff0c;然后到达插入文献的位置&#xff0c;右键点击。 选择切换域代码 将其…

国内首个,Postcat 上线 AI 生成 API 功能,写接口动几下就行

近期AI风潮席卷全球&#xff0c;Postcat 作为新一代 API 生产力工具&#xff0c;从发布的第一天起就在思考如何通过AIAPI以及插件化架构来更好的满足开发者的需求。 今天我们很高兴的向大家宣布&#xff0c;Postcat.com 正式上线 AI 生成 API 的功能&#xff0c;并且是国内首个…

【GO】 32.pprof

一 . 添加引用启动项目访问指标页面 1.1 在main程序添加pprof引用&#xff0c;并启动网页 "net/http" _ "net/http/pprof" go func() {log.Println(http.ListenAndServe(":6060", nil)) }() 1.2 访问pprof页面 http://127.0.0.1:6060/debug/…

10.MyBatis逆向工程

MyBatis逆向工程 正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库表。Hibernate是支持正向工程的。 逆向工程&#xff1a;先创建数据库表&#xff0c;由框架负责根据数据库表&#xff0c;反向生成如下资源&#xff1a; Java实体类Mapper接口M…

腾讯云服务器ping不通怎么解决?什么原因?

腾讯云服务器ping不通什么原因&#xff1f;ping不通公网IP地址还是域名&#xff1f;新手站长从云服务器公网IP、安全组、Linux系统和Windows操作系统多方面来详细说明腾讯云服务器ping不通的解决方法&#xff1a; 目录 腾讯云服务器ping不通原因分析及解决方法 安全组ICMP协…

CentOS7.9 k8s集群环境搭建

环境搭建 本次环境搭建需要安装三台Centos服务器(一主二从)&#xff0c;k8s采用1.25.4版本 主机安装 安装虚拟机过程中注意下面选项的设置&#xff1a; 操作系统环境&#xff1a;CPU(2C) 内存(4G) 硬盘(50G)语言选择&#xff1a;English软件选择&#xff1a;基础设施服务器分区…

某乎评论数据

文章目录 声明目标网址加密参数分析与首页测试翻页逻辑实现通用的csv保存全部采集代码整合往期逆向文章推荐很久没有看评论接口了,最近运行了一下旧的脚本,发现不能用,应该是也加了X-Zse-96校验,本篇就试着解决评论采集问题。 声明 本文章中所有内容仅供学习交流,严禁用于…

个人简历电子版免费范文(合集)

个人简历电子版免费范文篇1 基本信息 姓名&#xff1a;__ 性别&#xff1a;__ 出生日期&#xff1a;__ 籍贯&#xff1a;__市 目前城市&#xff1a;__市 联系电话&#xff1a;__ E-mail&#xff1a;__ 应聘方向 求职行业&#xff1a;金融/投资/证券&#xff0c;银行&#xff0c…

Rust 1.70.0 发布

导读Rust团队很高兴地宣布新版本的Rust&#xff0c;1.70.0。Rust是一种编程语言&#xff0c;使每个人都能建立可靠和高效的软件。 如果你通过rustup安装了以前的Rust版本&#xff0c;你可以用1.70.0获得&#xff1a; rustup update stable 如果你还没有&#xff0c;你可以从我…

记一次 .NET 某旅行社审批系统 崩溃分析

一&#xff1a;背景 1. 讲故事 前些天有位朋友找到我&#xff0c;说他的程序跑着跑着就崩溃了&#xff0c;让我看下怎么回事&#xff0c;其实没怎么回事&#xff0c;抓它的 crash dump 就好&#xff0c;具体怎么抓也是被问到的一个高频问题&#xff0c;这里再补一下链接&…

【Python 随练】求和序列

题目&#xff1a; 求 saaaaaaaaaaaa…a 的值&#xff0c;其中 a 是一个数字。 例如 222222222222222(此时共有 5 个数相加)&#xff0c;几个数相加有键盘控制。 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个求和问题&#xff1a;给定一个数字 a&#xff0c;求…

基于msm8953调试CST226SE触摸TP

目录 1、事件驱动和设备挂载 2、adb调试节点 3、修改设备树地址 4、修改驱动地址 5、修改firmware固件参数 我们总是习惯不断的搜索&#xff0c;阅读前人总结和分享的经验&#xff0c;在不断尝试中进步&#xff0c;如果没有大家的分享经验&#xff0c;学习和探索的过程将是多么…

基于Flask+Bootstrap+机器学习的世界杯比赛预测系统

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

云原生安全 - 构建强大的安全基石保障现代化应用

导言&#xff1a; 随着云原生技术的兴起和广泛应用&#xff0c;越来越多的企业将其应用于现代化应用开发和部署。然而&#xff0c;随之而来的安全威胁也随之增加。在这篇文章中&#xff0c;我们将探讨云原生安全的重要性&#xff0c;以及如何构建强大的安全基石来保障现代化应…