如何使用JavaScript或HTML实现图片懒加载以解决网站加载缓慢问题?
嘿,针对你遇到的图片一次性加载拖慢网站速度的问题,我整理了两种最实用的懒加载实现方案,分别是原生HTML方案(最简单省心)和JavaScript方案(兼容性更强、更灵活),你可以根据自己的需求选择:
1. 原生HTML懒加载(首推,零JS成本)
现在主流现代浏览器(Chrome、Firefox、Edge、Safari 15.4+等)都支持原生的图片懒加载,只需要给<img>标签加上loading="lazy"属性就行,完全不需要额外的JavaScript代码。
修改你的HTML代码如下:
<img loading="lazy" src="image1.jpg" alt="tempo traveller"> <img loading="lazy" src="image2.jpg" alt="tempo traveller">
这个属性有三个可选值:
lazy:开启懒加载,图片只有进入视口范围时才会加载eager:强制立即加载图片(默认行为,也就是你现在的状态)auto:由浏览器自行判断是否懒加载
这种方案的优势就是简单、高效、无额外性能开销,如果你的用户群体主要使用现代浏览器,这绝对是最佳选择。
2. JavaScript实现懒加载(兼容旧浏览器/自定义逻辑)
如果需要兼容比较老的浏览器(比如Safari 15.4以下版本),或者想要自定义图片的加载时机(比如提前一点距离就加载),可以用JavaScript来实现。这里推荐两种实现方式:
2.1 使用Intersection Observer API(性能最优)
Intersection Observer是浏览器提供的专门监听元素是否进入视口的API,相比传统的滚动监听,它的性能更好,不会因为频繁触发滚动事件导致页面卡顿。
步骤1:修改HTML结构
把真实的图片地址放到data-src属性中,src属性可以放一个占位图(比如极小的base64空白图,或者低分辨率的预览图):
<img data-src="image1.jpg" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="tempo traveller"> <img data-src="image2.jpg" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" alt="tempo traveller">
步骤2:编写JavaScript逻辑
document.addEventListener('DOMContentLoaded', function() { // 获取所有带data-src的图片 const lazyImages = document.querySelectorAll('img[data-src]'); // 创建观察器实例 const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { // 当图片进入视口时 if (entry.isIntersecting) { const img = entry.target; // 把data-src的值赋给src,开始加载图片 img.src = img.dataset.src; // 加载完成后停止监听该图片,避免重复触发 observer.unobserve(img); } }); }, { // 可选:提前200px开始加载图片,提升用户体验 rootMargin: '200px 0px' }); // 给每个懒加载图片添加监听 lazyImages.forEach(img => imageObserver.observe(img)); });
2.2 传统滚动监听(兼容极低版本浏览器)
如果需要兼容非常老的浏览器(不支持Intersection Observer),可以用传统的滚动监听方式,但记得加上防抖函数减少性能损耗:
步骤1:同样修改HTML结构(和上面一致)
<img data-src="image1.jpg" src="placeholder.jpg" alt="tempo traveller"> <img data-src="image2.jpg" src="placeholder.jpg" alt="tempo traveller">
步骤2:编写带防抖的JavaScript逻辑
document.addEventListener('DOMContentLoaded', function() { const lazyImages = document.querySelectorAll('img[data-src]'); // 防抖函数:减少事件触发频率,避免卡顿 function debounce(func, delay = 100) { let timer; return function() { clearTimeout(timer); timer = setTimeout(func, delay); }; } // 检查图片是否进入视口 function checkLazyImages() { lazyImages.forEach(img => { const rect = img.getBoundingClientRect(); // 判断图片是否在视口范围内 const isVisible = rect.top <= window.innerHeight && rect.bottom >= 0; if (isVisible && img.src !== img.dataset.src) { img.src = img.dataset.src; } }); } // 页面加载完成后先检查一次 checkLazyImages(); // 给滚动和窗口 resize 事件绑定防抖后的检查函数 window.addEventListener('scroll', debounce(checkLazyImages)); window.addEventListener('resize', debounce(checkLazyImages)); });
内容的提问来源于stack exchange,提问作者Ajay
相关产品推荐
相关产品推荐

