Back

仅使用 HTML 实现原生图片懒加载

仅使用 HTML 实现原生图片懒加载

Web 开发者不断寻求优化页面性能的方法,而图片往往是最大的挑战。虽然 JavaScript 库多年来一直主导着懒加载解决方案,但现代浏览器现在通过简单的 HTML 属性支持原生图片懒加载。这种内置功能消除了对外部依赖的需求,同时在所有主流浏览器中提供可靠的性能改进。

本文将解释如何仅使用 HTML 实现原生图片懒加载,涵盖浏览器支持、最佳实践以及可能影响网站性能的常见陷阱。

关键要点

  • 原生懒加载只需要 loading="lazy" HTML 属性
  • 始终指定 width 和 height 属性以防止布局偏移
  • 永远不要对首屏或 LCP 图片使用懒加载
  • 浏览器支持覆盖 95%+ 的用户,包括 Chrome、Firefox、Safari 和 Edge
  • 图片在达到计算的距离阈值时自动加载
  • 无需 JavaScript,但可以使用回退方案扩展浏览器支持
  • 性能改进通常带来 20-50% 的初始加载时间提升

什么是原生图片懒加载?

原生图片懒加载利用浏览器的内置能力,将图片加载推迟到需要时才进行。浏览器不会在页面首次渲染时加载所有图片,而是计算图片何时进入视口,并在它们即将可见之前加载它们。

这种方法与基于 JavaScript 的解决方案不同,因为它:

  • 无需额外的代码或库
  • 即使在 JavaScript 被禁用时也能工作
  • 使用优化的浏览器算法进行加载决策
  • 在不同设备和连接速度下提供一致的行为

浏览器自动处理关于视口距离、连接速度和加载阈值的所有复杂计算。

原生懒加载的浏览器支持

当前 loading 属性的浏览器支持覆盖所有主流浏览器:

  • Chrome:77+(2019年9月)
  • Firefox:75+(2020年4月)
  • Safari:15.4+(2022年3月)
  • Edge:79+(2020年1月)

这代表了超过 95% 的全球浏览器使用量,使原生懒加载成为大多数网站的可靠选择。不支持该属性的浏览器会简单地忽略它,正常加载图片而不会产生任何负面影响。

Loading 属性:核心实现

loading 属性接受三个值:

lazy

延迟加载直到图片达到与视口的计算距离:

<img src="product-image.jpg" loading="lazy" alt="Product description" width="400" height="300">

eager

强制立即加载,无论视口位置如何(这是默认行为):

<img src="hero-image.jpg" loading="eager" alt="Hero section" width="800" height="400">

auto(已弃用)

之前允许浏览器决定,但此值已被弃用,不应使用。

基本最佳实践

始终包含尺寸

实现原生图片懒加载最关键的方面是指定图片尺寸。没有 width 和 height 属性,浏览器无法为图片保留空间,导致布局偏移:

<!-- 正确实现 -->
<img src="gallery-1.jpg" loading="lazy" alt="Gallery image" width="300" height="200">

<!-- 使用内联样式的替代方案 -->
<img src="gallery-2.jpg" loading="lazy" alt="Gallery image" style="width: 300px; height: 200px;">

当未指定尺寸时,图片默认为 0×0 像素。这可能导致浏览器假设所有图片都适合视口,触发立即加载所有内容。

永远不要对首屏图片使用懒加载

在初始页面加载期间可见的关键图片永远不应使用 loading="lazy"。这包括:

  • 英雄图片
  • Logo 图片
  • 前几个产品图片
  • 初始视口中的任何图片
<!-- 首屏图片 - 立即加载 -->
<img src="hero-banner.jpg" alt="Main banner" width="1200" height="600">
<img src="featured-product.jpg" alt="Featured item" width="400" height="300">

<!-- 首屏以下图片 - 懒加载 -->
<img src="product-4.jpg" loading="lazy" alt="Product 4" width="400" height="300">
<img src="product-5.jpg" loading="lazy" alt="Product 5" width="400" height="300">

响应式图片的懒加载

对于使用 <picture> 元素的响应式图片,只需在回退的 <img> 元素上添加 loading 属性:

<picture>
  <source media="(min-width: 800px)" srcset="large-image.jpg 1x, large-image-2x.jpg 2x">
  <source media="(min-width: 400px)" srcset="medium-image.jpg 1x, medium-image-2x.jpg 2x">
  <img src="small-image.jpg" loading="lazy" alt="Responsive image" width="400" height="300">
</picture>

浏览器距离阈值的工作原理

浏览器不会等到图片完全进入视口才开始加载它们。相反,它们使用基于连接速度的距离阈值:

  • 4G 连接:图片在距离视口约 1,250px 时开始加载
  • 3G 及更慢连接:图片在距离视口约 2,500px 时开始加载

这些阈值确保图片在用户滚动到它们之前完成加载。在测试中,97.5% 的 4G 网络懒加载图片在变为可见的 10ms 内完全加载。

常见实现挑战

防止布局偏移

没有适当的尺寸,懒加载可能会增加累积布局偏移(CLS)。始终指定确切尺寸或使用 CSS 维持宽高比:

.lazy-image {
  width: 100%;
  height: auto;
  aspect-ratio: 16/9;
}

隐藏图片

在 Chrome、Safari 和 Firefox 中,使用 display: none 的图片不会懒加载。但是,使用 opacity: 0visibility: hidden 隐藏的图片仍会加载。彻底测试您的实现:

<!-- 不会懒加载 -->
<img src="hidden.jpg" loading="lazy" style="display: none;">

<!-- 会懒加载 -->
<img src="hidden.jpg" loading="lazy" style="opacity: 0;">

轮播和滑块图片

Chrome 121 改变了水平滚动图片的行为。轮播图片现在使用与垂直滚动相同的阈值,意味着它们在变为可见之前加载。这改善了用户体验但增加了带宽使用。

旧版浏览器的 JavaScript 回退

为了更广泛的浏览器支持,实现渐进增强方法:

<!-- 带回退的懒加载 -->
<img data-src="image.jpg" loading="lazy" alt="Description" width="400" height="300" class="lazy-fallback">

<script>
if ('loading' in HTMLImageElement.prototype) {
  // 支持原生懒加载
  const images = document.querySelectorAll('img[loading="lazy"]');
  images.forEach(img => {
    img.src = img.dataset.src;
  });
} else {
  // 加载回退库
  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>

性能影响和指标

实现原生图片懒加载通常带来:

  • 初始页面加载时间减少 20-50%
  • 带宽使用量减少 30-60%
  • 改善核心 Web 指标得分
  • 在较慢连接上提供更好的用户体验

使用浏览器开发者工具和性能监控服务(如 PageSpeed InsightsWebPageTest)监控您的实现。

测试您的实现

浏览器开发者工具

使用 Chrome DevTools 验证懒加载:

  1. 打开 DevTools(F12)
  2. 转到 Network 选项卡
  3. 按”Img”过滤
  4. 重新加载页面并慢慢滚动
  5. 观察图片在接近视口时加载

网络限制

测试不同的连接速度:

  1. 在 DevTools 中,转到 Network 选项卡
  2. 从限制下拉菜单中选择”Slow 3G”或”Fast 3G”
  3. 观察加载阈值如何变化

边缘情况和限制

打印行为

当用户打印页面时,所有图片都会立即加载,无论 loading 属性如何。这确保打印的文档包含所有图片。

SEO 考虑

搜索引擎爬虫可以无问题地访问懒加载图片。loading 属性不会对 SEO 产生负面影响,更快的页面加载可以改善搜索排名。

背景图片

loading 属性只适用于 <img><iframe> 元素。对于背景图片,您需要使用 Intersection Observer API 的 JavaScript 解决方案。

结论

原生图片懒加载提供了一种简单、有效的方法来改善页面性能,无需外部依赖。通过在首屏以下图片上添加 loading="lazy" 属性并遵循关于尺寸和视口考虑的最佳实践,您可以显著减少初始页面加载时间和带宽使用。

成功实现的关键在于理解何时使用懒加载、始终指定图片尺寸,以及在不同设备和连接速度下进行测试。凭借广泛的浏览器支持和零开销,原生懒加载应该成为每个前端开发者性能优化工具包的一部分。

常见问题

原生图片懒加载是一种浏览器功能,使用 HTML loading 属性将图片加载推迟到需要时才进行。浏览器根据连接速度和距离阈值计算图片何时进入视口,然后在它们对用户可见之前加载它们。

所有主流现代浏览器都支持原生懒加载,包括 Chrome 77+、Firefox 75+、Safari 15.4+ 和 Edge 79+。这代表了超过 95% 的全球浏览器使用量。不支持该属性的浏览器会简单地忽略它并正常加载图片。

是的,使用 loading lazy 时始终包含 width 和 height 属性。没有尺寸,浏览器无法为图片保留空间,导致布局偏移和潜在问题,浏览器可能假设所有图片都适合视口并立即加载所有内容。

不,永远不要在首屏图片上使用 loading lazy,特别是在初始页面加载期间可见的 LCP 图片。只对出现在首屏以下或初始视口外的图片应用懒加载,以避免减慢关键内容渲染。

行为取决于图片的隐藏方式。在大多数浏览器中,使用 display none 的图片不会懒加载,而使用 opacity 0 或 visibility hidden 隐藏的图片仍会加载。始终彻底测试您的实现以确保它按预期行为。

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers