多媒体:图像

媒体,主要是图像和视频,占平均网站下载字节数的 70% 以上。在下载性能方面,消除媒体和减小文件大小是低垂的果实。本文介绍了如何优化图像和视频以提高 Web 性能。

先决条件 安装基本软件,以及对客户端 Web 技术的基本了解。
目标 了解各种图像格式,它们对性能的影响,以及如何减少图像对页面整体加载时间的影响。

注意: 这是关于优化 Web 上多媒体交付的高级介绍,涵盖了通用原理和技术。有关更深入的指南,请参阅 https://web.dev/learn/images

为什么要优化您的多媒体?

对于平均网站,其带宽的 51% 来自图像,其次是视频,占 25%,因此可以肯定地说,解决和优化多媒体内容很重要。

您需要考虑数据使用情况。许多人使用的是限量数据计划,甚至按流量付费,他们实际上是按兆字节付费。这也不是新兴市场的问题。根据OFCOM 国家和地区技术追踪器 - H1 2018 (PDF),截至 2018 年,英国仍有 24% 的人使用按流量付费。

您还需要考虑内存,因为许多移动设备的 RAM 有限。重要的是要记住,当图像下载时,它们需要存储在内存中。

优化图像传递

尽管图像下载是带宽的最大消费者,但图像下载对感知性能的影响远远低于许多人的预期(主要是因为页面文本内容会立即下载,并且用户可以在图像到达时看到它们正在渲染)。但是,为了获得良好的用户体验,仍然重要的是让访问者能够尽快看到它们。

加载策略

大多数网站的最大改进之一是延迟加载折叠线以下的图像,而不是在初始页面加载时全部下载它们,而不管访问者是否滚动查看它们。许多 JavaScript 库可以为您实现此功能,例如lazysizes,浏览器供应商正在努力开发一个原生 lazyload 属性,该属性目前处于实验阶段。

除了加载图像子集之外,您还应该研究图像本身的格式

  • 您是否正在加载最优的文件格式?
  • 您是否已很好地压缩了图像?
  • 您是否正在加载正确的大小?

最优格式

最优文件格式通常取决于图像的特征。

注意: 有关图像类型的常规信息,请参阅图像文件类型和格式指南

SVG 格式更适合颜色较少且非照片写实的图像。这需要源代码以矢量图形格式可用。如果这样的图像仅作为位图存在,那么PNG 将是首选的备用格式。这些类型图案的示例包括徽标、插图、图表或图标(注意:SVG 远优于图标字体!)。两种格式都支持透明度。

PNG 可以保存三种不同的输出组合

  • 24 位颜色 + 8 位透明度 — 以大小为代价提供全色精度和平滑透明度。您可能希望避免这种组合,而选择 WebP(见下文)。
  • 8 位颜色 + 8 位透明度 — 提供不超过 255 种颜色,但保持平滑的透明度。大小不是太大。这些可能是您想要的 PNG。
  • 8 位颜色 + 1 位透明度 — 提供不超过 255 种颜色,并且每个像素仅提供无透明度或全透明度,这会使透明度边界看起来很硬且参差不齐。大小很小,但代价是视觉保真度。

用于优化 SVG 的良好在线工具是SVGOMG。对于 PNG,有ImageOptim 在线Squoosh

对于不具有透明度的摄影图案,可以选择更广泛的格式。如果您想稳妥起见,那么您可以选择压缩良好的渐进式 JPEG。渐进式 JPEG 与普通 JPEG 不同,它会渐进地渲染(因此得名),这意味着用户会看到一个低分辨率版本,随着图像下载变得更清晰,而不是图像以全分辨率从上到下加载,或者甚至仅在完全下载后才呈现。一个好的压缩器是 MozJPEG,例如,可以在在线图像优化工具Squoosh 中使用。质量设置 75% 应该会产生不错的结果。

其他格式改进了 JPEG 在压缩方面的能力,但并非所有浏览器都支持

  • WebP — 图像和动画图像的绝佳选择。WebP 提供比 PNG 或 JPEG 更好的压缩,支持更高的颜色深度、动画帧、透明度等(但不支持渐进显示)。除 macOS 桌面的 Safari 14 及更早版本外,所有主要浏览器都支持。

    注意: 尽管 Apple 宣布在 Safari 14 中支持 WebP,但 16.0 之前的 Safari 版本无法在 macOS 桌面 11/Big Sur 及更早版本上成功显示 .webp 图像。iOS 14 的 Safari 确实 成功显示 .webp 图像。

  • AVIF — 由于高性能和免版税的图像格式(甚至比 WebP 更有效,但支持范围不如 WebP 广泛),图像和动画图像的绝佳选择。现在 Chrome、Edge、Opera 和 Firefox 都支持它。Squoosh 是一个用于将以前的图像格式转换为 AVIF 的良好在线工具。
  • JPEG2000 — 曾经是 JPEG 的继任者,但仅在 Safari 中受支持。也不支持渐进显示。

鉴于 JPEG-XR 和 JPEG2000 的支持范围有限,并且还考虑了解码成本,JPEG 的唯一真正竞争者是 WebP。这就是为什么您也可以提供该格式的图像。这可以通过 <picture> 元素来完成,借助 <source> 元素使用type 属性

如果这一切听起来有点复杂,或者感觉对您的团队来说工作量太大,那么您也可以使用一些在线服务作为图像 CDN,这些服务将根据请求图像的设备或浏览器类型自动在运行时提供正确的图像格式。最大的两个是CloudinaryImage Engine

最后,如果您想在页面上包含动画图像,那么请知道 Safari 允许在 <img><picture> 元素中使用视频文件。这些还允许您为所有其他现代浏览器添加动画 WebP

html
<picture>
  <source type="video/mp4" src="giphy.mp4" />
  <source type="image/webp" src="giphy.webp" />
  <img src="giphy.gif" alt="A GIF animation" />
</picture>

提供最优尺寸

在图像交付中,"一刀切"的方法并不能产生最佳结果,这意味着对于较小的屏幕,您需要提供分辨率较小的图像,反之亦然,对于较大的屏幕,您需要提供分辨率较大的图像。最重要的是,您还需要为那些拥有高 DPI 屏幕(例如 "视网膜")的设备提供更高分辨率的图像。因此,除了创建大量中间图像变体外,您还需要一种方法来为正确的浏览器提供正确的文件。这就是您需要使用media 和/或sizes 属性来升级 <picture><source> 元素的地方。有关如何将所有这些属性结合在一起的详细文章,请参见此处

需要牢记的两个与高 dpi 屏幕相关的有趣影响是

控制图像下载的优先级(和顺序)

让最重要的图像比不太重要的图像更早地出现在访问者面前,可以改善感知性能。

首先要检查的是您的内容图像是否使用 <img><picture> 元素,以及您的背景图像是否在 CSS 中使用 background-image 定义 — <img> 元素中引用的图像比背景图像具有更高的加载优先级。

其次,随着优先级提示的采用,您可以通过将 fetchPriority 属性添加到图像标签来进一步控制优先级。优先级提示在图像上的一个示例用例是轮播,其中第一个图像的优先级高于后续图像。

渲染策略:防止加载图像时出现卡顿

由于图像异步加载,并在首次绘制后继续加载,如果它们的尺寸在加载之前没有定义,它们会导致页面内容发生重排。例如,当文本因加载的图像而被推到页面下方时。出于这个原因,设置 widthheight 属性非常重要,这样浏览器就可以在布局中为它们保留空间。

当在 HTML <img> 元素上包含图像的 widthheight 属性时,浏览器可以在图像加载之前计算出图像的纵横比。此纵横比用于保留显示图像所需的空格,从而减少或甚至防止图像下载并绘制到屏幕时发生的布局偏移。减少布局偏移是良好的用户体验和 Web 性能的主要组成部分。

浏览器在解析 HTML 时开始呈现内容,通常是在包括图像在内的所有资产下载之前。包含尺寸使浏览器能够为每个图像保留一个正确大小的占位符框,以便在首次呈现页面时加载图像时显示这些框。

Two screenshots the first without an image but with space reserved, the second showing the image loaded into the reserved space.

如果没有 widthheight 属性,就不会创建占位符空间,这会导致页面呈现后图像加载时出现明显的卡顿或布局偏移。页面重排和重绘会影响性能和可用性。

CLS 指标衡量页面加载时的卡顿,即可见内容在视窗中偏移了多少,以及偏移了多少。导致 CLS 不佳的主要原因是未声明尺寸的替换元素,这些元素在资产加载时会发生重排,包括图像、广告、嵌入和 iframe,没有大小或aspect-ratio 和 Web 字体。

在响应式设计中,当容器比图像窄时,通常使用以下 CSS 来防止图像超出其容器

css
img {
  max-width: 100%;
  height: auto;
}

虽然这对响应式布局很有用,但如果未包含宽度和高度信息,会导致卡顿和糟糕的 CLS,因为在解析 <img> 元素但图像未加载之前,如果没有任何高度信息,此 CSS 将有效地将高度设置为 0。当图像在页面最初呈现到屏幕后加载时,页面会重新流式传输和重新绘制,因为为新确定的高度创建空间,从而导致布局偏移。

浏览器有一种在实际图像加载之前对图像进行大小调整的机制。当 <img><video><input type="button"> 元素设置了 widthheight 属性时,它的纵横比会在加载时计算出来,并通过提供的尺寸提供给浏览器。

然后使用纵横比来计算高度,因此,将正确的大小应用于 <img> 元素,这意味着如果列出的尺寸在图像加载时不完全准确,上述卡顿不会发生或会降至最低。

纵横比仅用于在图像加载时保留空间。图像加载后,将使用加载的图像的内在纵横比或 aspect-ratio 属性的值,而不是属性中的纵横比。这确保它以正确的纵横比显示,即使属性尺寸不准确。

虽然过去十年开发人员的最佳实践可能建议省略 HTML <img> 的图像的 widthheight 属性,但由于纵横比映射,包含这两个属性被认为是开发人员的最佳实践。

对于任何背景图像,重要的是设置 background-color 值,这样在图像下载之前,任何叠加的内容仍然可以阅读。

结论

在本节中,我们研究了图像优化。现在您对如何优化平均网站平均带宽总量的 50% 有了基本的了解。这只是消耗用户带宽和减慢页面加载速度的几种媒体类型之一。让我们来看看视频优化,解决下一个 20% 的带宽消耗。