如何实现图片懒加载?

图片懒加载是一种延迟加载非关键资源的技术,它能显著减少页面初始加载时间、节省带宽并提升用户体验。其核心逻辑是:只有当图片滚动到即将进入用户可视区域时,才去加载真实的图片资源。

使用Intersection Observer API(现代方案)

这是目前实现懒加载最优雅和高效的方式。Intersection Observer API可以异步监听目标元素与其祖先元素或视口(viewport)的交叉状态。

<img data-src="path/to/real-image.jpg" class="lazy" src="placeholder.jpg" alt="描述">
const lazyImages = document.querySelectorAll('img.lazy');
const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src; // 将 data-src 的值赋给 src
      img.classList.remove('lazy');
      observer.unobserve(img); // 停止观察已加载的图片
    }
  });
});

lazyImages.forEach(img => observer.observe(img));

我们先将真实图片地址存储在data-src属性中,src属性则放一个占位图。当观察器检测到图片进入视口(entry.isIntersectingtrue)时,便将data-src的值赋给src,从而触发浏览器加载真实图片。加载完成后,停止对该图片的观察。

传统滚动事件监听方案

在不支持Intersection Observer的旧环境中,可以通过监听scroll事件,并手动计算图片位置来实现。

function lazyLoad() {
  const lazyImages = document.querySelectorAll('img.lazy');
  lazyImages.forEach(img => {
    if (isInViewport(img)) {
      img.src = img.dataset.src;
      img.classList.remove('lazy');
    }
  });
}

function isInViewport(el) {
  const rect = el.getBoundingClientRect();
  return rect.top < window.innerHeight && rect.bottom > 0;
}

// 使用防抖优化性能
window.addEventListener('scroll', debounce(lazyLoad, 16));
window.addEventListener('resize', lazyLoad);
window.addEventListener('load', lazyLoad); // 初始加载时也检查一次

isInViewport函数判断元素是否在可视区域内。为了避免scroll事件高频触发造成的性能问题,必须使用防抖(debounce)或节流(throttle)进行优化。

使用loading=”lazy”原生属性

对于现代浏览器,最简单的懒加载方法是使用HTML原生的loading属性。

<img src="image.jpg" loading="lazy" alt="描述">

浏览器会自动处理加载时机。这是当前的首选方案,因为它无需任何JavaScript,且由浏览器底层优化。但其具体行为和支持的滚动容器由浏览器决定,自定义程度较低。

在实际项目中,建议采用渐进增强策略:首先使用loading="lazy",对于不支持的浏览器,用JavaScript方案(优先Intersection Observer)作为回退。无论哪种方案,都要确保在图片加载失败时有适当的占位或错误处理,并为img标签设置明确的宽高,以避免布局偏移。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容