无论您在学习 Web 设计和开发方面进展到什么程度,<img>
元素都无需过多介绍。它于 1993 年在 Netscape(当时名为“Mosaic”)中推出,并于 1995 年添加到 HTML 规范中,长期以来,<img>
在 Web 平台中发挥着简单但强大的作用。开发人员使用 src
属性添加“源”图像文件,并在图像无法呈现或辅助技术请求替代方案时,使用 alt
属性提供文本替代方案。从那时起,浏览器只有一个任务:获取图像数据,然后尽快呈现它。
在 Web 开发历史的大部分时间里,处理图片并没有那么复杂。而且,尽管现代 Web 非常复杂,但处理图片的基本原理并没有改变:使用 Web 友好的图片格式以实现兼容性,使用合理的压缩来节省带宽,以及使用适合图片在页面布局中占据空间的尺寸。
使用固定宽度布局(就像我们以前认为我们对用户体验 Web 的方式有更多发言权时所做的那样)使这个过程变得简单。设置图像源的大小尤其容易。对于占据五百像素宽和三百像素高的空间的图像,只需指定相同大小的源图像即可。
响应式布局中的图片
除了灵活的布局和 CSS 媒体查询的使用外,“灵活的图片和媒体”是 响应式 Web 设计 的三个定义方面之一。为了使图片具有灵活性,开发人员开始使用 CSS 在图片(或所有图片,全站范围内)上设置 max-width: 100%
,以告诉浏览器的渲染引擎通过缩小图片来防止图片溢出其父容器。从视觉上看,这非常有效——缩小 栅格图片 在视觉上是无缝的。使用一两行 CSS,缩小后的图片始终看起来好像我们指定了一个旨在以该尺寸显示的图像源。当渲染引擎获得的图像数据多于图片在布局中所占空间所需的数据时,它们能够就如何渲染缩小后的图片做出明智的决策,并且可以这样做而不会引入任何视觉伪影或模糊。
您通常不希望放大图片,即以大于源图像固有尺寸的尺寸渲染 <img>
。显示的图片会显得模糊且颗粒感十足。
使用 img { max-width: 100% }
意味着当灵活容器调整大小时,图片将根据需要缩小。与设置更严格的 width: 100%
不同,这也确保了图片不会放大到超出其固有尺寸。长期以来,这就是处理图片的规则:使用浏览器理解的格式,使用合理的压缩级别,并且永远不要向上缩放图片。
但是,尽管这种方法在视觉上简单有效,但它带来了巨大的性能成本。由于 <img>
仅支持图像数据的单个源,因此这种方法要求我们提供一个图像资源,其固有尺寸与它可以显示的最大尺寸一样大。根据用户的视口大小,旨在占据布局中从 300px
到 2000px
宽的任何空间的图像,需要一个固有宽度至少为 2000px
的图像源。对于仅通过小视口查看页面的用户,一切看起来都符合预期——图像将正常缩放。在渲染的页面中,巨大的但缩小的源图像看起来与大小合适的图像没有什么不同。但是,他们仍然会传输和渲染 2000px
宽的图像,从而消耗大量带宽和处理能力,而没有任何实际好处。
随着第一批“Retina”设备的问世,情况变得更糟,因为显示密度与视口大小一起成为一个令人担忧的问题。图像源需要更大的固有宽度才能适应高密度显示屏。简单来说,密度加倍的显示屏需要两倍的图像像素才能尽可能清晰地渲染图像。
在这里,开发人员再次能够依靠渲染引擎在视觉上缩小图像的能力。通过在 src
中为浏览器提供 800px
宽的源图像,然后指定应使用 CSS 以 400px
宽显示它,结果是图像以双倍像素密度渲染
当然,从视觉上看,单个源图像经过裁剪以适应布局中尽可能大的空间和高密度显示屏,对所有用户都有效。在高密度显示屏上渲染的巨大高分辨率图像源在小型低密度显示屏上看起来会像任何其他小型低密度图像,但感觉会慢得多。用户将承担 4000 像素宽的巨大图像源的所有性能成本,而没有任何好处。
长期以来,<img>
主要做一件事——“获取图像数据并将其放在屏幕上”。可以肯定的是,它做得相当好,但 <img>
无法适应我们正在经历的浏览环境的巨大变化。虽然响应式 Web 设计已成为主流开发实践,但浏览器对 img
的性能进行了近二十年的优化——但对于除极少数特权用户之外的所有用户来说,页面的图像内容从一开始就是低效的。无论浏览器管理请求、解析和渲染图像源的速度有多快,该资源都可能比用户需要的要大得多。