预加载主要图片(首屏图片)有助于减少Core Web Vitals中的最大内容绘制(LCP) 时间。这些通常是图像,如徽标、博客文章上的特色图像、登录页面上的Hero图像等。通过预加载它们,您将它们移动到瀑布的顶部,并基本上告诉浏览器这些具有优先级并且应该立即加载。
最大的内容绘制时间
重要的是要了解Chrome有两个图像预加载的限制,它们将出现在瀑布的最顶部。在这两个图像之后的任何内容仍然会在瀑布中显示得更高,但不会被视为高优先级,这完全取决于Chrome。我们通常建议预加载2-3个图像。这通常会预加载您的徽标并在博客文章中显示特色图片。
如果您在页面上有手动图像预加载,这将优先于自动预加载之一。
预加载关键图像功能还将自动从延迟加载中排除这些图像。
从Chrome 73开始,链接 和响应式图像可以结合起来,以便更快地加载图像。
预加载概述
Preload让您可以在HTML中发现关键资源之前尽快告诉浏览器您想要加载的关键资源。这对于不容易发现的资源特别有用,例如样式表中包含的字体、背景图像或从脚本加载的资源。
<link as="image" href="important.png">
响应式图像 + 预加载 = 更快的图像加载
响应式图像和预加载在过去几年中一直可用,但同时缺少一些东西:无法预加载响应式图像。从Chrome 73开始,浏览器可以在发现标签img
之前预加载srcset
指定的响应图像的正确变体!
根据您网站的结构,这可能意味着图像显示速度显着加快!我们在一个使用JavaScript延迟加载响应式图像的网站上进行了测试。预加载导致图像加载速度提高了1.2秒。
所有现代浏览器都支持响应式图像,而仅在基于Chromium的浏览器中支持预加载它们。
imagesrcset
和imagesizes
为了预加载响应式图像,最近向<link>
元素添加了新属性:imagesrcset
和imagesizes
. 它们与 <link rel="preload">
一起使用,并与 <img>
元素中使用的srcset
和sizes
语法相匹配。
例如,如果您想预加载指定的响应式图像:
<img src="wolf.jpg" alt="A rad wolf">
您可以通过将以下内容添加到您的HTML的<head>
来做到这一点:
<link as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw">
这将使用srcset
和sizes
将应用的相同资源选择逻辑启动请求。
用例
预加载动态注入的响应图像
假设您正在动态加载主图像作为幻灯片的一部分,并且知道将首先显示哪个图像。在这种情况下,您可能希望避免在加载相关图像之前等待脚本,因为这会延迟用户看到它的时间。
您可以在具有动态加载的图片库的网站上检查此问题:
- 在新选项卡中打开此示例网站。
- 按 `Control+Shift+J`(或 Mac 上的 `Command+Option+J`)打开DevTools。
- 单击网络选项卡。
- 在Throttling下拉列表中,选择Fast 3G。
- 禁用禁用缓存复选框。
- 重新加载页面。
此瀑布显示图像仅在浏览器完成运行脚本后才开始加载,从而对最初向用户显示图像的时间引入了不必要的延迟。
在此处使用preload
帮助是因为图像会提前开始加载,并且在浏览器需要显示它时可能已经存在。
此瀑布显示第一张图片与脚本同时开始加载,避免了不必要的延迟并加快了图片的显示速度。
要查看预加载的不同之处,您可以按照第一个示例中的步骤检查相同的动态加载的图像库,但预加载了第一张图像。
避免该问题的另一种方法是使用基于标记的轮播并让浏览器的预加载器获取所需的资源。然而,这种方法可能并不总是实用的。(例如,如果您正在重用现有的组件,它不是基于标记的。)
使用图像集预加载背景图像
如果对于不同的屏幕密度有不同的背景图像,则可以在CSS中使用image-set
语法指定它们。然后浏览器可以根据屏幕的DPR选择显示哪一个。
background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);
上述语法忽略了在基于Chromium和WebKit的浏览器中此功能需要供应商前缀这一事实。如果您打算使用此功能,则应考虑使用Autoprefixer(作为在线工具提供)来自动解决该问题。
CSS背景图片的问题在于,它们只有在浏览器下载并处理了页面<head>
中的所有CSS之后才会被浏览器发现,这可能是很多CSS……
您可以在具有响应式背景图像的示例网站上检查此问题。
在此示例中,直到 CSS 完全下载后才开始图像下载,从而导致图像显示出现不必要的延迟。
响应式图像预加载提供了一种简单且无需破解的方式来更快地加载这些图像。
<link rel=preload href=cat.png as=image imagesrcset="cat.png 1x, cat-2x.png 2x">
您可以检查前面的示例如何处理预加载的响应式背景图像。
在这里,图像和CSS同时开始下载,避免了延迟,从而加快了图像的加载速度。
预加载响应式图像
理论上,预加载响应式图像可以加快速度,但实际上它有什么作用呢?
为了回答这个问题,我们来看看创建了一个演示PWA商店的两个副本:一个不预加载图像,另一个预加载其中的一些。由于该站点使用JavaScript延迟加载图像,因此可能会从预加载将在初始视口中的图像受益。
这给了我以下关于no preload和image preload的结果。查看原始数据,我们看到Start Render保持不变,速度指数略有提高(273 毫秒,因为图像到达速度更快,但不占用大量像素区域),但捕捉差异的真实指标是最后绘制的Hero指标,提高了1.2 秒。
当然,没有什么比幻灯片比较更能捕捉视觉差异了:
幻灯片显示,图像在预加载时的到达速度明显更快,从而极大地改善了用户体验。
预加载和<picture>
?
如果您熟悉响应式图像,您可能想知道“怎么<picture>
办?”。
Web性能工作组正在讨论为srcset
and添加一个等效的预加载sizes
,但不是为处理 “art direction” 用例的<picture>
元素。
为什么这个用例被“忽视”?
尽管也有兴趣解决该用例,但仍有许多技术问题需要解决,这意味着这里的解决方案将具有很大的复杂性。最重要的是,在大多数情况下,用例似乎可以在今天得到解决,即使是以一种hacky的方式(见下文)。
鉴于此,Web Performance WG决定srcset
先发布,看看是否需要同等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 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=”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)”>
<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)">
小结
响应式图像预加载为我们提供了新的和令人兴奋的可能性,以以前只能使用hack的方式预加载响应式图像。它是对速度敏感的开发人员工具箱的重要新增功能,使我们能够确保我们希望尽快呈现在用户面前的重要图像在我们需要时会出现。