JavaScript 图片懒加载的三种实现方案:基础、节流与 IntersectionObserver

作者:青柠

时间:2026-10-21

浏览:272

本文详解 JavaScript 实现图片懒加载的三种方式。首先介绍通过 data-src 属性替换 src 的基础方法;其次针对 scroll 事件高频触发问题,引入函数节流(throttle)优化性能;最后讲解利用现代浏览器支持的 IntersectionObserver API 实现自动观察元素可见性的简洁方案,帮助提升长页面加载速度与用户体验。

文章目录

图片懒加载原理与优势

延迟加载,亦称惰性加载,是指在长网页中推迟加载图像资源的策略。

只有当用户滚动页面,使图像进入浏览器视口范围时,这些图像才会开始加载。

这与图像预加载机制相反。在长网页应用中采用延迟加载策略,能够显著加快页面的初始加载速度。

在特定场景下,这种策略还有助于降低服务器端的负载压力。

延迟加载的主要优势包括:

显著提升用户体验。若页面图片数量庞大,一次性全部加载会导致页面卡顿。通过按需请求图片,不仅能有效减轻服务器带宽压力和流量消耗,也能降低浏览器的渲染负担。

基础实现方案

方法一:基础实现

实现思路是将页面上所有图片的 src 属性临时设置为一个占位图(如 loading.gif),而将真实的图片路径存储在 data-src 自定义属性中。

在页面滚动过程中,实时计算图片相对于视口的位置与当前滚动距离。一旦检测到图片进入浏览器可视区域,便将图片的 src 属性更新为 data-src 中存储的真实路径。


<img src="loading.png" data-src="image.png">

img { display: block; margin-bottom: 50px; }

function lazyload() {
 var images = document.getElementsByTagName('img');
 var n = 0; // 用于存储图片加载到的位置,避免每次都从第一张图片开始遍历 
 return function() {
 var seeHeight = document.documentElement.clientHeight;
 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
 for(var i = n; i < images.length; i++) {
  if (images[i].offsetTop < seeHeight + scrollTop) {
  if (images[i].getAttribute('src') === 'loading.png') {
   images[i].src = images[i].getAttribute('data-src');
  }
  n = n + 1;
  }
 }
 }
}
lazyload(); //初始化首页的页面图片
window.addEventListener('scroll', lazyload(), false);

基于函数节流的性能优化

方法二:性能优化

上述基础方法虽然逻辑简单,但存在性能隐患。由于 scroll 事件在滚动时会高频触发,频繁执行计算逻辑会严重影响浏览器性能。因此,需要对 lazyload 函数应用函数节流(throttle)或函数去抖(debounce)技术进行处理。

函数节流与去抖机制

此处 HTML 和 CSS 代码保持不变,经过 throttle 处理后的 JavaScript 代码如下:


function throttle (fn, delay, atleast) {
 var timeout = null,
  startTime = new Date();
 return function () {
 var curTime = new Date();
 clearTimeout(timeout);
 if (curTime - startTime >= atleast) {
  fn ();
  startTime = curTime;
 } else {
  timeout = setTimeout (fn, delay);
 }
 }
}

function lazyload() {
 var images = document.getElementsByTagName('img'),
  n = 0;  //存储图片加载到的位置,避免每次都从第一张图片开始遍历 
 return function() {
 var seeHeight = document.documentElement.clientHeight;
 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
 for(var i = n; i < images.length; i++) {
  if(images[i].offsetTop < seeHeight + scrollTop) {
  if(images[i].getAttribute('src') === 'loading.png') {
   images[i].src = images[i].getAttribute('data-src');
  }
  n = n + 1;
  }
 }
 }
}
lazyload(); //初始化首页的页面图片
window.addEventListener('scroll', throttle(lazyload(), 500, 1000), false);

使用 IntersectionObserver API 的现代方案

方法三:使用 IntersectionObserver API

现代浏览器提供了新的 IntersectionObserver API,它能够自动“观察”元素是否进入可视区域。

该方法的代码实现非常简洁,但需注意许多旧版浏览器尚不支持此 API。

图片懒加载原理与优势

  • IntersectionObserver 接收一个回调函数,当被观察的元素集合进入或离开视口时,该回调函数会被执行。
  • 通过 io.observe 方法,需要逐个添加希望被观察的元素。
  • IntersectionObserver 实例内部管理着一个元素数组。当元素进入或离开视口时,它会自动在数组中添加或移除该元素,并触发相应的回调函数执行。


function query(selector) {
 return Array.from(document.querySelectorAll(selector));
}
var io = new IntersectionObserver(function(items) {
 items.forEach(function(item) {
 var target = item.target;
 if(target.getAttribute('src') == 'loading.png') {
  target.src = target.getAttribute('data-src');
 }
 })
});
query('img').forEach(function(item) {
 io.observe(item);

以上即为本文介绍的全部内容,希望这些实现方式能对您的学习有所帮助,欢迎继续支持本站获取更多技术分享。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章