针对 Web 的浏览器级图片延迟加载

Browser Support

  • Chrome: 77.
  • Edge: 79.
  • Firefox: 75.
  • Safari: 15.4.

您可以使用 loading 属性延迟加载图片,而无需编写自定义延迟加载代码或使用单独的 JavaScript 库。以下是此功能的 演示

延迟加载的图片会在用户滚动浏览网页时加载。

本页详细介绍了如何在浏览器中实现延迟加载。

为何要使用浏览器级延迟加载?

根据 HTTP Archive 的数据, 图片是大多数网站请求最多的资源类型,并且通常 比任何其他资源占用更多带宽。在第 90 个百分位,网站在桌面设备和移动设备上发送的图片超过 5 MB。

以前,有两种方法可以延迟加载屏幕外图片:

这两种方法都可以让开发者包含延迟加载行为,许多开发者都构建了第三方库,以提供更易于使用的抽象。

不过,如果浏览器直接支持延迟加载,则无需使用外部库。浏览器级延迟加载还可确保即使客户端停用 JavaScript,图片加载仍能正常运行。但请注意,只有在启用 JavaScript 时,加载才会延迟。

loading 属性

Chrome 会根据图片相对于设备视口的位置,以不同的优先级加载图片。视口下方的图片会以较低的优先级加载,但仍会在网页加载时提取。

您可以使用 loading 属性完全延迟加载屏幕外图片:

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

以下是 loading 属性支持的值:

  • lazy:延迟加载资源,直到资源到达与视口的 计算距离为止。
  • eager:浏览器的默认加载行为,与不包含该属性相同,这意味着无论图片在网页上的哪个位置,都会加载。这是默认值,但如果您的工具在没有明确值时自动添加 loading="lazy",或者您的代码检查工具在未明确设置时发出警告,则明确设置该值可能会很有用。

loading 属性与提取优先级之间的关系

eager 值是一条指令,用于指示按正常方式加载图片,如果图片位于屏幕外,则不会进一步延迟加载。它不会比没有 loading 属性的其他图片加载得更快。

如果您想提高重要图片(例如, LCP 图片)的提取优先级,请使用 提取优先级,并将 fetchpriority="high"

如果图片具有 loading="lazy"fetchpriority="high",则在图片位于屏幕外时仍会延迟加载,然后在图片几乎位于视口内时以高优先级提取。这种组合实际上没有必要,因为浏览器很可能会以高优先级加载该图片。

与视口的距离阈值

所有无需滚动即可立即查看的图片都会正常加载。只有当用户滚动到设备视口下方很远的位置时,才会提取这些图片。

Chromium 的延迟加载实现会尝试确保屏幕外图片加载得足够早,以便在用户滚动到这些图片时完成加载,方法是在这些图片在视口中显示之前提取它们。

距离阈值因以下因素而异:

您可以在 Chromium 源代码中找到不同有效连接类型的默认值。 您可以通过在开发者工具中 限制网络 来尝试这些不同的阈值。

改进的数据节省和与视口的距离阈值

2020 年 7 月,Chrome 进行了重大改进,使图片延迟加载与视口的距离阈值与开发者的预期更加一致。

在快速连接 (4G) 上,我们将 Chrome 与视口的距离阈值从 3000px 降低到 1250px;在较慢的连接(3G 或更低)上,我们将阈值从 4000px 更改为 2500px。此更改实现了以下两点:

  • <img loading=lazy> 的行为更接近 JavaScript 延迟加载库提供的体验。
  • 新的与视口的距离阈值仍然意味着图片很可能在用户滚动到这些图片时加载完毕。

接下来,您可以在快速连接 (4G) 上找到我们的一个演示的旧版与新版与视口的距离阈值之间的比较:

针对图片延迟加载功能推出了经过改进的新阈值,将快速连接的视口距离阈值从 3,000 像素降至 1,250 像素。
浏览器级延迟加载使用的旧版与新版阈值的比较。

以及新阈值与 LazySizes(一个热门的 JavaScript 延迟加载库)的比较:

在相同的网络条件下,Chrome 加载 90 KB 图片时的新视口距离阈值与 LazySizes 加载 70 KB 图片时的视口距离阈值。
Chrome 和 LazySizes 中用于延迟加载的阈值的比较。

为图片提供尺寸属性

在浏览器加载图片时,除非明确指定,否则它不会立即知道图片的尺寸。为了让浏览器在网页上为图片预留 足够的空间,并避免破坏性 布局偏移, 我们建议您向所有 <img> 标记添加 widthheight 属性。

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

或者,直接在内嵌样式中指定其值:

<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">

无论您是否延迟加载 <img> 标记,设置尺寸的最佳实践都适用,但延迟加载可能会使其更加重要。

Chromium 中的延迟加载实现方式使得图片更有可能在显示后立即加载,但仍有可能无法在正确的时间加载。如果发生这种情况,则在图片上不指定 widthheight 会增加其对累积布局偏移的影响。如果您无法指定图片的尺寸,则延迟加载图片可以节省网络 资源,但可能会增加这些增加的 布局偏移的风险。

在大多数情况下,如果您不指定尺寸,图片仍会延迟加载,但有一些极端情况需要注意。如果不指定 widthheight,图片尺寸默认设置为 0×0 像素。如果您有一个图片库,浏览器可能会决定所有图片都适合在开始时位于视口内,因为每张图片都不占用空间,并且没有图片被推送到屏幕外。在这种情况下,浏览器会决定加载所有内容,从而导致网页加载速度变慢。

如需了解 loading 如何处理大量图片,请参阅 此 演示

您还可以延迟加载使用 <picture> 元素定义的图片:

<picture>
  <source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
  <img src="photo.jpg" loading="lazy">
</picture>

虽然浏览器会决定从任何 <source> 元素加载哪个图片,但您只需将 loading 添加到回退 <img> 元素即可。

始终预加载第一个视口中可见的图片

对于用户首次加载网页时可见的图片,尤其是 LCP 图片,请使用浏览器的默认预加载,以便它们可以立即使用。如需了解详情,请参阅延迟加载过多对性能的影响

仅对初始视口外的图片使用 loading=lazy。浏览器只有在知道图片在网页上的位置后才能延迟加载图片,这会导致图片加载速度变慢。

<!-- visible in the viewport -->
<img src="product-1.jpg" alt="..." width="200" height="200">
<img src="product-2.jpg" alt="..." width="200" height="200">
<img src="product-3.jpg" alt="..." width="200" height="200">

<!-- offscreen images -->
<img src="product-4.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-5.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-6.jpg" loading="lazy" alt="..." width="200" height="200">

优雅降级

不支持 loading 属性的浏览器会忽略该属性。它们无法获得延迟加载的好处,但包含该属性不会产生负面影响。

常见问题解答

下面围绕浏览器级延迟加载解答了一些常见问题。

我可以在 Chrome 中自动延迟加载图片吗?

以前,如果 Android 版 Chrome 启用了精简模式,并且未提供 loading 属性或将其设置为 loading="auto",则 Chromium 会自动延迟加载任何适合延迟加载的图片。不过, 精简模式和 loading="auto" 已被弃用 并且没有计划在 Chrome 中提供自动延迟加载图片的功能。

我可以更改图片在加载前需要与视口之间的距离吗?

这些值是硬编码的,无法通过 API 更改。不过,随着浏览器尝试不同的阈值距离和变量,这些值将来可能会发生变化。

CSS 背景图片可以使用 loading 属性吗?

不可以,您只能将其与 <img> 标记搭配使用。

使用 loading="lazy" 可以 防止在图片不可见但位于 计算距离内时加载图片。 这些图片可能位于轮播界面后面,或者被 CSS 隐藏以适应特定屏幕尺寸。例如,Chrome、Safari 和 Firefox 不会使用 display: none; 样式加载图片,无论是在图片元素上还是在父元素上。不过,其他图片隐藏技术(例如使用 opacity:0 样式)仍会导致浏览器加载图片。请务必全面测试您的实现,以确保其按预期运行。

Chrome 121 更改了横向滚动图片(如轮播界面)的行为。这些图片现在使用与纵向滚动相同的阈值。这意味着,对于轮播界面用例,图片将在视口中显示之前加载。这意味着用户不太可能注意到图片加载,但会增加下载量。使用横向延迟加载演示比较 Chrome 与 Safari 和 Firefox 中的行为。

如果我已使用第三方库或脚本延迟加载图片,该怎么办?

由于现代浏览器内置了对延迟加载的全面支持,因此您可能不需要使用第三方库或脚本来延迟加载图片。

继续将第三方库与 loading="lazy" 搭配使用的一个原因是,为不支持该属性的浏览器提供 Polyfill,或者 更好地控制何时触发延迟加载。

如何处理不支持延迟加载的浏览器?

所有主流浏览器都很好地支持浏览器级图片延迟加载,建议在大多数用例中使用,以避免对 JavaScript 的额外依赖。

不过,如果您需要支持更多浏览器,或者想要更好地控制延迟加载阈值,则可以使用第三方库来延迟加载网站上的图片。

您可以使用 loading 属性来检测浏览器是否支持该功能:

if ('loading' in HTMLImageElement.prototype) {
  // supported in browser
} else {
  // fetch polyfill/third-party library
}

例如,lazysizes 是一个热门的 JavaScript 延迟加载库。您可以检测对 loading 属性的支持,以便仅在不支持 loading 时将 lazysizes 加载为回退库。具体操作如下:

  • <img src> 替换为 <img data-src>,以避免在 不支持的浏览器中进行预加载。如果支持 loading 属性,请将 data-src 替换为 src
  • 如果不支持 loading,请从 lazysizes 加载回退并启动它,使用 lazyload 类来指示要延迟加载的图片:
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">

<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">

<script>
  if ('loading' in HTMLImageElement.prototype) {
    const images = document.querySelectorAll('img[loading="lazy"]');
    images.forEach(img => {
      img.src = img.dataset.src;
    });
  } else {
    // Dynamically import the LazySizes library
    const script = document.createElement('script');
    script.src =
      'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
    document.body.appendChild(script);
  }
</script>

以下是此模式的演示。在旧版浏览器中尝试一下,看看回退的实际效果。

浏览器是否也支持 iframe 的延迟加载?

Browser Support

  • Chrome: 77.
  • Edge: 79.
  • Firefox: 121.
  • Safari: 16.4.

<iframe loading=lazy> 也已标准化。这样,您就可以使用 loading 属性延迟加载 iframe。如需了解详情,请参阅是时候延迟加载屏幕外 iframe 了!

浏览器级延迟加载对网页上的广告有何影响?

以图片或 iframe 形式向用户显示的所有广告都会像任何其他图片或 iframe 一样延迟加载。

打印网页时如何处理图片?

打印网页时,所有图片和 iframe 都会立即加载。如需了解详情,请参阅 问题 #875403

Lighthouse 是否识别浏览器级延迟加载?

Lighthouse 6.0 及更高版本考虑了 屏幕外图片延迟加载的方法,这些方法可以使用不同的阈值, 从而让它们通过 延迟加载屏幕外图片审核。

延迟加载图片以提升性能

浏览器对延迟加载图片的支持可以显著简化您提升网页性能的过程。

您是否注意到在 Chrome 中启用此功能后出现任何异常行为?请提交 bug