预加载自适应图片

发布时间:2019 年 9 月 30 日,上次更新时间:2026 年 7 月 10 日

您可以预加载自适应图片,这有助于浏览器在呈现 img 标记之前从 srcset 中识别正确的图片,从而显著加快图片加载速度。

自适应图片概览

Browser Support

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 78.
  • Safari: 17.2.

Source

假设您在宽度为 300 像素的屏幕上浏览网页,而该网页请求的图片宽度为 1500 像素。该网页浪费了大量移动数据,因为您的屏幕无法处理所有额外的分辨率。 理想情况下,浏览器会提取比屏幕尺寸稍宽的图片版本,例如 325 像素。 这样可以确保图片具有高分辨率,同时不会浪费数据,并加快图片加载速度。

自适应图片 让浏览器可以为不同的设备提取不同的图片资源。如果您不 使用图片 CDN,请为每张 图片保存多个尺寸,并在srcset属性中指定这些尺寸。w 值会告知浏览器每个版本的宽度,以便浏览器为任何设备选择合适的版本:

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

预加载概览

Browser Support

  • Chrome: 50.
  • Edge: 79.
  • Firefox: 85.
  • Safari: 11.1.

Source

借助预加载,您可以告知浏览器您想要尽快加载的 关键资源,而无需在 HTML 中 发现这些资源。这对于不易发现的资源(例如样式表中的字体、背景图片或从脚本加载的资源)尤其有用。

<link rel="preload" as="image" href="important.png" fetchpriority="high">

imagesrcsetimagesizes

<link> 元素使用 imagesrcsetimagesizes 属性来 预加载自适应图片。将它们与 <link rel="preload"> 搭配使用,并使用srcsetsizes 语法在 <img> 元素中使用。

例如,如果您想预加载使用以下内容指定的自适应图片:

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

您可以通过将以下内容添加到 HTML 的 <head> 中来实现此目的:

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw" fetchpriority="high">

这会使用与 srcsetsizes 相同的资源选择逻辑来发起请求。

使用场景

以下是预加载自适应图片的一些使用场景。

预加载动态注入的自适应图片

假设您要动态加载主打图片作为幻灯片的一部分,并且您知道哪张图片将首先显示。在这种情况下,您可能希望尽快显示该图片,而不是等待幻灯片脚本加载该图片。

您可以在具有动态加载的图片库的网站上检查此问题:

  1. 在新标签页中打开此幻灯片演示
  2. Control+Shift+J(或在 Mac 上按 Command+Option+J)打开 DevTools。
  3. 点击网络 标签页。
  4. 节流 下拉列表中,选择 Fast 3G
  5. 取消选中 Disable cache 复选框。
  6. 重新加载页面。
Chrome 开发者工具的“网络”面板,其中显示了一个瀑布图,其中包含一个仅在某些 JavaScript 之后才开始下载的 JPEG 资源。
如果不进行预加载,图片会在浏览器运行完脚本后开始加载。对于第一张图片,这种延迟是不必要的。

在此处使用 preload 可让图片提前开始加载,以便在浏览器需要显示图片时,图片可以准备好显示。

Chrome 开发者工具的“网络”面板:显示了瀑布图,其中一个 JPEG 资源与一些 JavaScript 并行下载。
预加载第一张图片可让其与脚本同时开始加载。

如需了解预加载带来的差异,请检查相同的动态加载的 图片库,但预加载了第一张图片 ,具体方法是按照第一个示例中的步骤操作。

使用 image-set 预加载背景图片

如果您为不同的屏幕密度使用不同的背景图片,则可以使用 image-set 语法在 CSS 中指定这些图片。然后,浏览器可以根据屏幕的 DPR选择要显示的图片。

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

CSS 背景图片的问题在于,浏览器只有在下载并处理网页 <head> 中的所有 CSS 后才会发现它们 。

您可以在具有 自适应背景图片的示例网站上检查此问题。

Chrome 开发者工具“网络”面板,其中显示了一个瀑布图,其中包含一个仅在下载某些 CSS 后才开始下载的 JPEG 资源。
在此示例中,图片下载不会在 CSS 完全下载之前开始,从而导致图片显示出现不必要的延迟。

借助自适应图片预加载,您可以更快地加载这些图片。

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x" fetchpriority="high">

如果省略 href 属性,您可以确保不支持 <link> 元素上的 imagesrcset 但支持 CSS 中的 image-set 的浏览器下载正确的来源。不过,在这种情况下,它们不会从预加载中受益。

您可以在自适应背景预加载演示中检查上一个示例在预加载了自适应 背景图片后的行为。

Chrome 开发者工具“网络”面板,显示了一个瀑布图,其中一个 JPEG 资源与一些 CSS 并行下载。
在这里,图片和 CSS 同时开始下载,从而加快图片加载速度。

预加载自适应图片的实际效果

从理论上讲,预加载自适应图片可以加快图片加载速度,但实际上会带来什么效果呢?

为了回答这个问题,我创建了两个演示 PWA 商店副本: 一个不预加载图片, 另一个预加载部分图片。 由于该网站使用 JavaScript 延迟加载图片,因此预加载初始视口中显示的图片可能会带来好处。

这产生了以下结果: 不预加载预加载图片

WebPageTest 影片胶片对比图,显示预加载的图片显示速度快了大约 1.5 秒。
预加载后,图片加载速度显著加快,从而大大提升了用户体验。

预加载和 <picture>

Web Performance Working Group 正在讨论为 srcsetsizes 添加等效的预加载,但不是 <picture> 元素,该元素处理 "艺术指导" 用例。

预加载 <picture> 仍有许多 技术问题需要解决, 但在此期间,有一些解决方法:

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

<picture> 元素的图片来源选择逻辑按顺序检查 media 属性的 <source> 元素,找到第一个匹配的属性,并使用附加的资源。

由于自适应预加载没有“顺序”或“第一个匹配项”的概念,因此您需要将断点转换为类似以下内容:

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)" fetchpriority="high">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)" fetchpriority="high">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)" fetchpriority="high">

预加载和 type

<picture> 元素还支持匹配第一个 type,以便您提供不同的图片格式,让浏览器选择它支持的第一个图片格式。

预加载仅部分支持此用例:浏览器应仅下载受支持类型的预加载。因此,您可以使用此方法来防止浏览器预加载不受支持的 MIME 类型,方法是在预加载中添加以下内容:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">

不过,与 <picture> 不同,它不会在第一个受支持的类型处停止。因此,如果为多个类型添加了多个预加载,则所有图片都将被预加载:

请勿执行此操作 - 预加载多种类型:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">
<link rel="preload" href="image.jpg" type="image/jpg" as="image" fetchpriority="high">

请改为执行此操作 - 预加载最首选的类型:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">

预加载最新格式(在本例中为 AVIF)可作为渐进式增强功能,支持该类型的浏览器将受益,而其他浏览器将无法从预加载中受益。

对于 HTML 中可以快速发现图片的网站,我们建议避免预加载,而是让预加载扫描器<picture><source>元素中提取图片。无论如何,这都是一种最佳实践,尤其是在使用 Fetch Priority 帮助确定适当图片的优先级时,因为它允许根据浏览器支持情况预加载确切的图片。它还可以消除在图片或网页更改时预加载过时于主要标记的风险。

对 Largest Contentful Paint (LCP) 的影响

由于图片可以是 Largest Contentful Paint (LCP) 候选对象, 预加载图片可以提升网站的 LCP。

无论您预加载的图片是否具有自适应性,当图片资源在初始标记载荷中不可发现时,预加载效果最佳。 此外,在客户端呈现标记的网站上,您还可以获得比从服务器发送完整标记的网站更高的 LCP 提升。