导读:本期聚焦于小伙伴创作的《如何实现懒加载?javascript中图片懒加载的原理是什么?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何实现懒加载?javascript中图片懒加载的原理是什么?》有用,将其分享出去将是对创作者最好的鼓励。

图片懒加载指的是当页面滚动到图片所在可视区域时,才加载图片资源,避免首屏一次性加载所有图片导致页面加载缓慢、浪费用户流量的问题。该方案能有效提升首屏加载速度,降低服务器请求压力。

如何实现懒加载?javascript中图片懒加载的原理是什么?

图片懒加载的核心原理

图片懒加载的核心逻辑是暂时不将图片的真实地址赋值给<img>标签的src属性,而是把真实地址存储在其他自定义属性中(通常使用data-src)。当页面滚动时,判断<img>标签是否进入浏览器的可视区域,如果进入就将data-src的值赋值给src属性,触发图片加载。

传统实现方案:基于滚动事件判断

传统方案通过监听window的scroll事件,结合DOM元素的位置信息和可视区域高度来判断图片是否进入可视区。需要用到以下三个关键属性:

  • offsetTop:元素相对于其offsetParent顶部的距离
  • scrollTop:页面滚动的距离,即文档顶部被卷去的高度
  • clientHeight:浏览器可视区域的高度

判断逻辑为:当元素的offsetTop小于等于scrollTop加上clientHeight时,说明元素已经进入可视区域。

传统方案实现代码

// 获取所有需要懒加载的图片
const lazyImages = document.querySelectorAll('img[data-src]');

// 判断图片是否进入可视区的函数
function isInViewport(img) {
  const rect = img.getBoundingClientRect();
  // getBoundingClientRect返回元素相对于可视区域的位置信息
  return rect.top <= window.innerHeight && rect.bottom >= 0;
}

// 加载图片的函数
function loadImage(img) {
  const src = img.getAttribute('data-src');
  if (src) {
    img.src = src;
    // 加载完成后移除data-src属性,避免重复处理
    img.removeAttribute('data-src');
  }
}

// 处理懒加载的函数
function handleLazyLoad() {
  lazyImages.forEach(img => {
    if (isInViewport(img)) {
      loadImage(img);
    }
  });
}

// 初始加载时先执行一次,加载首屏可视区的图片
handleLazyLoad();
// 监听滚动事件
window.addEventListener('scroll', handleLazyLoad);

这种方案需要注意滚动事件触发频率很高,可能会导致性能问题,通常需要搭配节流函数优化:

// 节流函数,限制函数在一定时间内只执行一次
function throttle(fn, delay) {
  let timer = null;
  return function() {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, arguments);
        timer = null;
      }, delay);
    }
  };
}

// 使用节流后的滚动监听
window.addEventListener('scroll', throttle(handleLazyLoad, 200));

现代实现方案:Intersection Observer API

Intersection Observer API是浏览器提供的原生接口,用于异步观察目标元素与祖先元素或顶级文档视口的交叉状态,不需要手动计算位置,性能更优,代码更简洁。

Intersection Observer实现代码

// 获取所有需要懒加载的图片
const lazyImages = document.querySelectorAll('img[data-src]');

// 创建观察器实例
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    // 判断元素是否进入可视区
    if (entry.isIntersecting) {
      const img = entry.target;
      const src = img.getAttribute('data-src');
      if (src) {
        img.src = src;
        img.removeAttribute('data-src');
      }
      // 图片加载完成后停止观察该元素
      observer.unobserve(img);
    }
  });
}, {
  // 提前50px触发加载,提升用户体验
  rootMargin: '0px 0px 50px 0px'
});

// 遍历所有图片,开始观察
lazyImages.forEach(img => {
  observer.observe(img);
});

两种方案对比

两种实现方案的特点对比如下:

方案类型优势劣势适用场景
滚动事件方案兼容性更好,支持更多老版本浏览器需要手动计算位置,滚动事件频繁需要节流,性能相对较差需要兼容老版本浏览器的项目
Intersection Observer方案原生API支持,无需手动计算,性能优异,代码简洁兼容性稍差,不支持IE等老版本浏览器面向现代浏览器的项目

注意事项

  • 图片的<img>标签初始src可以设置为占位图或者空值,避免浏览器发送无效请求
  • 如果页面存在动态新增的图片,需要给新增的图片也添加data-src属性,并重新执行观察逻辑
  • 使用Intersection Observer时,可以通过rootMargin参数调整触发加载的提前量,避免用户滚动到图片位置时才开始加载导致等待

图片懒加载javascriptIntersection_Observerdata_src性能优化修改时间:2026-06-21 12:06:17

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