预加载自适应图片

您可以预加载自适应图片,具体做法是帮助浏览器在呈现 img 标记之前从 srcset 中识别出正确的图片,从而显著加快图片的加载速度。

自适应图片概览

浏览器支持

  • 73
  • 79
  • 78
  • 17.2

假设您正在一个宽度为 300 像素的屏幕上浏览网页,而相应网页请求了一张宽度为 1500 像素的图片。该网页浪费了您的大量移动流量,因为这样的话,您的屏幕就无法执行任何操作。理想情况下,浏览器会提取仅比屏幕尺寸宽一点的图片版本,例如 325 像素。这样可以确保获取高分辨率的图像而不浪费数据,并加快图像加载速度。

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

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

预加载概览

浏览器支持

  • 50
  • 不超过 79
  • 85
  • 11.1

来源

借助预加载,您可以告知浏览器您想要尽快加载的关键资源,避免在 HTML 中发现这些资源。这对于不容易检测到的资源特别有用,例如样式表中包含的字体、背景图片或从脚本加载的资源。

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

imagesrcsetimagesizes

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

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

 <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">

这将使用 srcsetsizes 使用的资源选择逻辑发出请求。

用例

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

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

假设您要动态加载幻灯片中的主打图片,并且知道最先显示哪张图片。在这种情况下,您可能需要尽快显示该图片,而不是等待幻灯片演示脚本加载该图片。

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

  1. 在新标签页中打开此幻灯片演示
  2. Control+Shift+J(在 Mac 上,按 Command+Option+J)即可打开开发者工具。
  3. 点击网络标签页。
  4. Throttling 下拉列表中,选择 Fast 3G
  5. 取消选中停用缓存复选框。
  6. 重新加载页面。
Chrome DevTools 的 Network 面板的屏幕截图。
如果不预加载,图片会在浏览器运行完脚本后开始加载。对于第一张图片,不需要该延迟。

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

Chrome DevTools Network 面板的屏幕截图。
预加载第一张图片,可让它与脚本同时开始加载。

如需了解预加载的不同之处,请按照第一个示例中的步骤检查同一个动态加载的图库,但预加载了第一张图片

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

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

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

CSS 背景图片的问题是,浏览器只有在下载并处理了页面 <head> 中的所有 CSS 后,才会发现这些图片。

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

Chrome DevTools Network 面板的屏幕截图。
在此示例中,在 CSS 完全下载之前,图片下载不会开始,这会导致图片的显示出现不必要的延迟。

自适应图片预加载功能可让您更快地加载这些图片。

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

不指定 href 属性可确保对于不支持 <link> 元素上的 imagesrcset,但支持 CSS 中的 image-set 的浏览器,您可以下载正确的源代码。但在这种情况下,它们不会从预加载中受益。

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

Chrome DevTools Network 面板的屏幕截图。
在这里,图片和 CSS 会同时开始下载,从而加快图片的加载速度。

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

从理论上讲,预加载自适应图片可以加快图片加载速度,但实际上它有何作用?

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

对于无预加载图片预加载,会生成以下结果:

WebPageTest 幻灯片比较的屏幕截图,显示预加载图片的显示速度加快了约 1.5 秒。
在预加载后,图片到达速度会显著加快,从而极大地改善了用户体验。

预加载和 <picture>

Web 性能工作组正在讨论为 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> 元素的图片来源选择逻辑会按顺序查看 <source> 元素的 media 属性,查找第一个匹配的属性,并使用附加的资源。

由于响应式预加载没有“顺序”或“首次匹配”的概念,因此您需要将断点转换为如下所示的内容:

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

预加载和 type

<picture> 元素还支持与第一个 type 匹配,让您可以提供不同的图片格式,以便浏览器可以选择其支持的第一种图片格式。预加载功能不支持此用例。

对于使用类型匹配的网站,我们建议您避免预加载,而让预加载扫描程序<picture><source> 元素中提取图片。无论如何,这都是最佳实践,尤其是在使用优先级提示来帮助确定适当映像的优先级时。

对 Largest Contentful Paint (LCP) 的影响

由于图片可能是 Largest Contentful Paint (LCP) 候选版本,因此预加载它们可以提高网站的 LCP。

无论您要预加载的图片是否为自适应图片,当在初始标记载荷中无法发现该图片资源时,预加载的效果最好。此外,与从服务器发送完整标记的网站相比,在客户端呈现标记的网站也会进一步提升 LCP 效果。