图片懒加载的核心思路是让页面可视区外的图片暂不加载,等到用户滚动到对应位置再触发加载,结合html原生的loading属性和自定义html函数可以高效实现这一功能,同时还能通过优化手段降低性能开销。

基础实现:用html函数生成带loading属性的图片
我们可以封装一个html函数,专门用来生成带有懒加载配置的图片标签,默认给图片添加loading="lazy"属性,同时支持自定义其他参数。
// 封装生成懒加载图片的html函数
function createLazyImage(src, alt = '默认图片描述', className = '') {
// 转义特殊字符避免xss问题
const safeSrc = src.replace(/&/g, '&').replace(//g, '>');
const safeAlt = alt.replace(/&/g, '&').replace(//g, '>');
// 生成带loading属性的img标签
return `<img src="${safeSrc}" alt="${safeAlt}" class="${className}" loading="lazy">`;
}
// 使用示例
const imageHtml = createLazyImage('https://ipipp.com/demo.jpg', '示例图片', 'lazy-img');
// 将生成的html插入到页面容器中
document.getElementById('image-container').innerHTML = imageHtml;loading属性的工作原理
html原生的loading属性是浏览器内置的懒加载支持,取值为lazy时,浏览器会自动判断图片是否进入可视区,进入后再发起资源请求。这种方式不需要额外监听滚动事件,减少了js运行的开销,但默认的触发阈值和加载逻辑可能不符合所有场景的需求。
默认loading属性的性能问题
- 浏览器默认的懒加载触发距离较近,用户快速滚动时可能会出现图片加载不及时的情况
- 如果页面中大量使用loading="lazy",浏览器会同时监控所有图片的位置,带来一定的内存开销
- 部分低版本浏览器不支持loading属性,需要做兼容处理避免功能失效
性能优化方案
1. 自定义触发阈值优化加载时机
我们可以通过IntersectionObserver API配合html函数,自定义图片进入可视区前多少距离就触发加载,避免用户滚动到位置才加载的延迟问题。
// 优化后的懒加载html函数,支持自定义触发阈值
function createOptimizedLazyImage(src, alt = '默认图片描述', className = '', rootMargin = '200px') {
const safeSrc = src.replace(/&/g, '&').replace(//g, '>');
const safeAlt = alt.replace(/&/g, '&').replace(//g, '>');
// 生成带唯一标识的img标签,方便后续监听
const imgId = `lazy-img-${Date.now()}-${Math.random().toString(36).slice(2)}`;
return {
html: `<img id="${imgId}" data-src="${safeSrc}" alt="${safeAlt}" class="${className}">`,
id: imgId,
rootMargin: rootMargin
};
}
// 初始化观察器,自定义触发阈值
function initLazyObserver(rootMargin = '200px') {
if (!('IntersectionObserver' in window)) {
// 不支持observer的浏览器直接加载所有图片
document.querySelectorAll('img[data-src]').forEach(img => {
img.src = img.dataset.src;
img.removeAttribute('data-src');
});
return;
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.removeAttribute('data-src');
observer.unobserve(img);
}
});
}, { rootMargin: rootMargin });
return observer;
}
// 使用示例
const observer = initLazyObserver('200px');
const imageInfo = createOptimizedLazyImage('https://ipipp.com/demo2.jpg', '优化后的示例图', 'optimized-lazy-img');
document.getElementById('image-container').innerHTML += imageInfo.html;
observer.observe(document.getElementById(imageInfo.id));2. 批量处理减少监控开销
如果页面中有大量图片,不要逐个创建观察器,而是共用一个观察器实例,所有图片都添加到同一个观察器中,加载完成后取消监听,这样可以大幅减少内存占用。
3. 低版本浏览器兼容处理
对于不支持loading属性和IntersectionObserver的浏览器,可以在html函数生成标签时判断环境,直接给图片设置src属性,避免懒加载功能失效导致图片无法显示。
优化效果对比
我们可以通过下表对比不同实现方式的性能表现:
| 实现方式 | 首屏请求数 | js运行开销 | 内存占用 |
|---|---|---|---|
| 原生loading属性 | 低 | 极低 | 中等 |
| 未优化的自定义html函数 | 低 | 高 | 高 |
| 优化后的自定义html函数 | 低 | 低 | 低 |
实际开发中可以根据项目需求选择合适的实现方式,大部分现代浏览器场景优先使用原生loading属性配合简单的html函数即可,对加载时机有更高要求的场景再使用优化后的自定义方案。
图片懒加载html_loading属性性能优化html函数修改时间:2026-06-07 05:54:59