温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

前端JS图片懒加载原理是什么

发布时间:2023-02-24 17:28:51 来源:亿速云 阅读:181 作者:iii 栏目:开发技术

前端JS图片懒加载原理是什么

目录

  1. 引言
  2. 什么是图片懒加载
  3. 图片懒加载的原理
  4. 实现图片懒加载的几种方式
  5. 图片懒加载的性能优化
  6. 图片懒加载的优缺点
  7. 图片懒加载的实际应用场景
  8. 总结

引言

在现代Web开发中,图片是网页内容的重要组成部分。然而,随着图片数量和质量的增加,页面加载时间也随之增加,这可能会影响用户体验和SEO排名。为了解决这个问题,前端开发者们引入了图片懒加载技术。本文将详细介绍图片懒加载的原理、实现方式、性能优化以及实际应用场景。

什么是图片懒加载

图片懒加载(Lazy Loading)是一种延迟加载图片的技术。它的核心思想是:只有当图片进入用户的可视区域(视口)时,才加载该图片。这样可以减少页面初始加载时的请求数量,从而加快页面加载速度,提升用户体验。

图片懒加载的原理

3.1 监听滚动事件

图片懒加载的核心在于监听用户的滚动行为。当用户滚动页面时,页面内容会不断进入和离开视口。通过监听滚动事件,我们可以判断哪些图片即将进入视口,从而触发图片的加载。

3.2 判断图片是否进入视口

为了判断图片是否进入视口,我们需要获取图片的位置信息。通常,我们可以通过getBoundingClientRect()方法来获取图片相对于视口的位置。如果图片的顶部或底部进入视口,我们就可以认为该图片需要被加载。

3.3 加载图片

一旦判断出图片需要被加载,我们就可以通过修改图片的src属性来触发图片的加载。通常情况下,我们会将图片的真实URL存储在data-src属性中,当图片进入视口时,再将data-src的值赋给src属性。

实现图片懒加载的几种方式

4.1 原生JavaScript实现

使用原生JavaScript实现图片懒加载是最基础的方式。以下是一个简单的实现示例:

document.addEventListener("DOMContentLoaded", function() {
  let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Fallback for older browsers
    let active = false;

    const lazyLoad = function() {
      if (active === false) {
        active = true;

        setTimeout(function() {
          lazyImages.forEach(function(lazyImage) {
            if ((lazyImage.getBoundingClientRect().top <= window.innerHeight && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") {
              lazyImage.src = lazyImage.dataset.src;
              lazyImage.classList.remove("lazy");

              lazyImages = lazyImages.filter(function(image) {
                return image !== lazyImage;
              });

              if (lazyImages.length === 0) {
                document.removeEventListener("scroll", lazyLoad);
                window.removeEventListener("resize", lazyLoad);
                window.removeEventListener("orientationchange", lazyLoad);
              }
            }
          });

          active = false;
        }, 200);
      }
    };

    document.addEventListener("scroll", lazyLoad);
    window.addEventListener("resize", lazyLoad);
    window.addEventListener("orientationchange", lazyLoad);
  }
});

4.2 Intersection Observer API

Intersection Observer API是现代浏览器提供的一个API,用于异步观察目标元素与其祖先元素或顶级文档视口的交叉状态。使用这个API可以更高效地实现图片懒加载。

document.addEventListener("DOMContentLoaded", function() {
  let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Fallback for older browsers
    let active = false;

    const lazyLoad = function() {
      if (active === false) {
        active = true;

        setTimeout(function() {
          lazyImages.forEach(function(lazyImage) {
            if ((lazyImage.getBoundingClientRect().top <= window.innerHeight && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") {
              lazyImage.src = lazyImage.dataset.src;
              lazyImage.classList.remove("lazy");

              lazyImages = lazyImages.filter(function(image) {
                return image !== lazyImage;
              });

              if (lazyImages.length === 0) {
                document.removeEventListener("scroll", lazyLoad);
                window.removeEventListener("resize", lazyLoad);
                window.removeEventListener("orientationchange", lazyLoad);
              }
            }
          });

          active = false;
        }, 200);
      }
    };

    document.addEventListener("scroll", lazyLoad);
    window.addEventListener("resize", lazyLoad);
    window.addEventListener("orientationchange", lazyLoad);
  }
});

4.3 使用第三方库

除了原生JavaScript和Intersection Observer API,我们还可以使用一些第三方库来实现图片懒加载。这些库通常提供了更丰富的功能和更好的兼容性。常见的第三方库包括:

  • Lozad.js: 一个轻量级的图片懒加载库,基于Intersection Observer API
  • LazyLoad: 一个功能强大的图片懒加载库,支持图片、iframe、背景图等多种资源的懒加载。
  • Vanilla LazyLoad: 一个简单易用的图片懒加载库,支持原生JavaScript和jQuery。

以下是一个使用Lozad.js的示例:

<img class="lozad" data-src="image.jpg" alt="Lazy loaded image">
const observer = lozad('.lozad', {
  rootMargin: '10px 0px', // 提前加载的距离
  threshold: 0.1 // 触发加载的阈值
});
observer.observe();

图片懒加载的性能优化

5.1 节流与防抖

在实现图片懒加载时,频繁的滚动事件可能会影响页面性能。为了减少不必要的计算和请求,我们可以使用节流(throttle)和防抖(debounce)技术来优化滚动事件的触发频率。

  • 节流: 在一定时间内只执行一次回调函数。
  • 防抖: 在一定时间内,如果事件再次触发,则重新计时,直到事件停止触发后才执行回调函数。

以下是一个使用节流的示例:

function throttle(func, limit) {
  let inThrottle;
  return function() {
    const args = arguments;
    const context = this;
    if (!inThrottle) {
      func.apply(context, args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}

window.addEventListener('scroll', throttle(lazyLoad, 200));

5.2 预加载

为了进一步提升用户体验,我们可以在图片进入视口之前提前加载部分图片。这可以通过设置rootMargin参数来实现。rootMargin允许我们指定一个额外的边距,使得图片在进入视口之前就开始加载。

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
}, {
  rootMargin: '0px 0px 200px 0px' // 提前200px加载
});

document.querySelectorAll('img.lazy').forEach(img => {
  observer.observe(img);
});

5.3 图片占位符

在图片加载完成之前,页面可能会出现空白区域,这会影响用户体验。为了解决这个问题,我们可以使用图片占位符(Placeholder)来填充空白区域。常见的占位符包括:

  • 纯色背景: 使用与图片主题色相近的纯色背景。
  • 低分辨率图片: 使用低分辨率的缩略图作为占位符。
  • SVG占位符: 使用SVG图形作为占位符,通常用于复杂的图片布局。

以下是一个使用低分辨率图片作为占位符的示例:

<img class="lazy" src="placeholder.jpg" data-src="image.jpg" alt="Lazy loaded image">

图片懒加载的优缺点

6.1 优点

  • 减少初始加载时间: 通过延迟加载图片,可以减少页面初始加载时的请求数量,从而加快页面加载速度。
  • 节省带宽: 对于用户来说,只有当他们滚动到图片所在位置时,图片才会被加载,这可以节省带宽。
  • 提升用户体验: 页面加载速度的提升可以显著改善用户体验,特别是在移动设备上。

6.2 缺点

  • 兼容性问题: 虽然现代浏览器支持Intersection Observer API,但在一些旧版浏览器中可能需要使用回退方案。
  • SEO影响: 如果图片懒加载实现不当,可能会影响搜索引擎对图片的索引。
  • 复杂性增加: 实现图片懒加载需要额外的代码和逻辑,这可能会增加项目的复杂性。

图片懒加载的实际应用场景

图片懒加载技术广泛应用于各种Web场景中,特别是在以下情况下:

  • 图片密集型网站: 如图片分享网站、电商网站等,这些网站通常包含大量图片,使用懒加载可以显著提升页面加载速度。
  • 长页面: 对于内容较长的页面,用户可能不会一次性浏览所有内容,使用懒加载可以减少初始加载时间。
  • 移动端网页: 移动设备的网络环境通常较差,使用懒加载可以减少流量消耗,提升用户体验。

总结

图片懒加载是一种有效的前端优化技术,通过延迟加载图片,可以减少页面初始加载时间,提升用户体验。本文详细介绍了图片懒加载的原理、实现方式、性能优化以及实际应用场景。希望本文能帮助你更好地理解和应用图片懒加载技术,从而提升你的Web项目的性能。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

js
AI