JavaScript如何实现图片与组件的懒加载

来源:站长工具作者:美谷头衔:网络博主
导读:本期聚焦于小伙伴创作的《JavaScript如何实现图片与组件的懒加载》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript如何实现图片与组件的懒加载》有用,将其分享出去将是对创作者最好的鼓励。

JavaScript懒加载是一种常见的前端性能优化手段,核心思路是延迟加载非首屏可见的图片和组件,只有当这些资源进入浏览器的可视区域时,才触发实际的加载逻辑,从而减少初始页面的资源请求数量,加快首屏渲染速度。

JavaScript如何实现图片与组件的懒加载

懒加载的实现原理

懒加载的核心依赖两个关键判断:一是判断元素是否已经进入可视区域,二是判断元素是否还未被加载过。浏览器提供了IntersectionObserver接口,可以高效监听元素与可视区域的交叉状态,不需要手动计算元素的位置和滚动距离,性能比传统的滚动事件监听更好。

对于不支持IntersectionObserver的旧浏览器,也可以通过监听scroll事件,结合getBoundingClientRect方法计算元素的位置,判断是否在可视区域内,不过这种方式需要注意防抖处理,避免滚动时频繁触发计算逻辑。

图片懒加载的实现

图片懒加载是最常见的应用场景,通常我们会给需要懒加载的图片设置一个自定义属性存储真实的图片地址,初始时src属性为空或者放一张占位图,当图片进入可视区域时,把自定义属性的值赋值给src属性,触发图片加载。

基于IntersectionObserver的实现

首先准备HTML结构,给懒加载的图片添加data-src属性存储真实地址:

<div class="img-container">
  <img class="lazy-img" data-src="https://ipipp.com/img1.jpg" alt="示例图片1">
</div>
<div class="img-container">
  <img class="lazy-img" data-src="https://ipipp.com/img2.jpg" alt="示例图片2">
</div>
<div class="img-container">
  <img class="lazy-img" data-src="https://ipipp.com/img3.jpg" alt="示例图片3">
</div>

接下来编写JavaScript逻辑:

// 获取所有需要懒加载的图片元素
const lazyImgs = document.querySelectorAll('.lazy-img');

// 创建IntersectionObserver实例
const imgObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    // 判断元素是否进入可视区域
    if (entry.isIntersecting) {
      const img = entry.target;
      // 获取真实图片地址
      const realSrc = img.dataset.src;
      if (realSrc) {
        // 赋值给src触发加载
        img.src = realSrc;
        // 加载完成后移除data-src属性,避免重复处理
        img.removeAttribute('data-src');
      }
      // 停止监听当前元素
      imgObserver.unobserve(img);
    }
  });
}, {
  // 提前100px触发加载,提升用户体验
  rootMargin: '100px'
});

// 遍历所有懒加载图片,开始监听
lazyImgs.forEach(img => {
  imgObserver.observe(img);
});

传统scroll事件实现方式

如果需要兼容不支持IntersectionObserver的环境,可以使用以下实现:

// 获取所有懒加载图片
const lazyImgs = document.querySelectorAll('.lazy-img');

// 防抖函数,避免滚动时频繁执行
function debounce(fn, delay) {
  let timer = null;
  return function() {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
}

// 判断元素是否在可视区域
function isInViewport(el) {
  const rect = el.getBoundingClientRect();
  return rect.top < window.innerHeight && rect.bottom > 0;
}

// 加载图片的逻辑
function loadLazyImgs() {
  lazyImgs.forEach(img => {
    // 已经加载过的图片跳过
    if (img.dataset.loaded) return;
    if (isInViewport(img)) {
      const realSrc = img.dataset.src;
      if (realSrc) {
        img.src = realSrc;
        img.dataset.loaded = true;
      }
    }
  });
}

// 初始执行一次
loadLazyImgs();
// 监听滚动事件,使用防抖处理
window.addEventListener('scroll', debounce(loadLazyImgs, 200));

组件懒加载的实现

组件懒加载通常用于单页应用中,比如Vue、React等框架的路由组件,或者页面中体积较大、非首屏需要的组件。这里以原生JavaScript实现动态加载组件为例,思路是当组件容器进入可视区域时,动态创建script标签加载组件的JS文件,或者动态渲染组件的HTML内容。

首先准备组件容器:

<div class="component-container" data-component="large-component">
  <!-- 组件加载前的占位内容 -->
  <p>组件加载中...</p>
</div>

对应的JavaScript实现逻辑:

// 获取所有需要懒加载的组件容器
const lazyComponents = document.querySelectorAll('.component-container');

// 创建IntersectionObserver实例监听组件容器
const componentObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const container = entry.target;
      const componentName = container.dataset.component;
      if (componentName && !container.dataset.loaded) {
        // 动态加载组件的逻辑,这里以加载JS文件为例
        const script = document.createElement('script');
        script.src = `https://ipipp.com/components/${componentName}.js`;
        script.onload = () => {
          // 假设组件JS加载完成后会暴露一个init方法
          if (window[componentName] && typeof window[componentName].init === 'function') {
            window[componentName].init(container);
          }
          container.dataset.loaded = true;
        };
        document.body.appendChild(script);
      }
      // 停止监听当前容器
      componentObserver.unobserve(container);
    }
  });
}, {
  rootMargin: '200px'
});

// 开始监听所有组件容器
lazyComponents.forEach(container => {
  componentObserver.observe(container);
});

如果是使用框架开发,比如Vue3,可以直接使用内置的defineAsyncComponent实现组件懒加载,React则可以使用React.lazySuspense组合实现,核心逻辑和原生实现一致,都是延迟加载组件的代码,在需要的时候再请求资源。

懒加载的注意事项

  • 给懒加载的元素设置合适的宽高,避免加载完成后页面布局偏移,影响用户体验。
  • 合理设置rootMargin参数,提前触发加载,避免用户滚动到元素位置时才开始加载,出现空白等待的情况。
  • 加载完成后及时停止监听元素,减少不必要的性能消耗。
  • 对于关键的首屏图片和组件,不要使用懒加载,避免影响首屏渲染速度。

JavaScript懒加载图片延迟加载组件延迟加载修改时间:2026-07-06 05:27:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。