仅使用 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: 0
或 visibility: 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 Insights 或 WebPageTest)监控您的实现。
测试您的实现
浏览器开发者工具
使用 Chrome DevTools 验证懒加载:
- 打开 DevTools(F12)
- 转到 Network 选项卡
- 按”Img”过滤
- 重新加载页面并慢慢滚动
- 观察图片在接近视口时加载
网络限制
测试不同的连接速度:
- 在 DevTools 中,转到 Network 选项卡
- 从限制下拉菜单中选择”Slow 3G”或”Fast 3G”
- 观察加载阈值如何变化
边缘情况和限制
打印行为
当用户打印页面时,所有图片都会立即加载,无论 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 隐藏的图片仍会加载。始终彻底测试您的实现以确保它按预期行为。