JavaScript实现懒加载


前言

       身为开发人员的我们进行项目开发时,不仅仅要对页面进行设计,而且还要考虑项目上线后是否能进行性能优化,从而达到减轻对服务器的负载,让用户拥有一个友好的项目体验感。常见的项目性能优化方式有很多。例如:减少HTTP请求,减少DNS查询,避免重定向,图片懒加载等。接下来,为大家介绍项目性能优化之一 — 图片懒加载。

一、懒加载是什么?

       懒加载也叫 延迟加载,按需加载。指的是在长网页中延迟加载图片数据,是一种较好的网页性能优化的方式。在比较长的网页或应用中,如果图片很多,所有的图片都被加载出来,而用户只能看到可视窗口的那一部分图片数据,这样就浪费了性能。
       如果使用图片的懒加载就可以解决以上问题。在滚动屏幕之前,可视化区域之外的图片不会进行加载,在滚动屏幕时才加载。这样使得网页的加载速度更快,减少了服务器的负载。懒加载适用于图片较多,页面列表较长(长列表)的场景中。
原文链接:点击跳转

二、懒加载的特点。

  • 减少无用资源的加载:使用懒加载明显减少了服务器的压力和流量,同时也减小了浏览器的负担和服务器的负载。
  • 提升用户体验: 如果同时加载较多图片,可能需要等待的时间较长,这样影响了用户体验,而使用懒加载就能大大的提高用户体验。
  • 防止加载过多图片而影响其他资源文件的加载 :会影响网站应用的正常使用。

三、懒加载的实现原理。

  • 首先准备需要的img标签。图片(注意:此处包含了未加载时需要展示的图片)
  • img标签src属性都设置为未加载时展示图片的路径,并设置对应的data-xxx(此处我使用data-src)为真正需要展示图片的路径。
  • 判断当前图片是否已经进入用户浏览器的可视区域,若未进入,则继续展示未加载时展示的图片;如已进入,则将data-src中真正的图片路径动态赋值给src属性,从而将图片进行加载,最后达到懒加载的功能。

四、实现懒加载。

使用原生JavaScript实现

 <div id="imgs">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img01.webp" alt="blank">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img02.webp" alt="blank">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img03.webp" alt="blank">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img04.webp" alt="blank">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img05.webp" alt="blank">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img06.webp" alt="blank">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img07.webp" alt="blank">
        <img src="./images/img01.webp" class="img-item" data-src="./images/img08.webp" alt="blank">
    </div>
<script>
        const imgs = document.getElementsByClassName('img-item')
        function getScroll() {
            // 先获取设备的可视区域高度
        	const vh = document.documentElement.clientHeight || window.innerHeight || document.body.clientHeight

            // 获取滑动区域的偏移高度
            const top = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset
            // 
            for (const i in imgs) {
                if (imgs[i].offsetTop < (vh + top)) {
                    imgs[i].src = imgs[i].dataset.src //将data-src属性值赋值给src
                }
            }
        }

        // 节流函数的封装
        function mythrottle(fn, interval) {
            // 设置记录上一次触发的时间变量
            let lastTime = 0
            // 设置对应的变量进行执行函数的接收
            const _mythrottle = function () {
                // 获取当前事件触发的时间
                let nowTime = new Date().getTime()
                // 获取执行函数的arguments
                const args = arguments
                // 计算等待时间
                let waitTime = interval - (nowTime - lastTime)
                // 判断当前是否允许执行对应的逻辑代码函数
                if (waitTime <= 0) {
                    fn.apply(this, args)
                    lastTime = nowTime
                }
            }
            return _mythrottle
        }
        // 将scroll时间绑定在window元素上
        window.onscroll = mythrottle(getScroll, 200)
    </script>

五、懒加载结果展示。

       可以观察到只有当用户将图片滑动至浏览器可视区域,真正的图片地址才会被请求,从而达到懒加载的效果(注意: 视频有背景音乐,请谨慎播放)。

新增

IntersectionObserver

关键 API

Intersection Observer API:创建一个回调函数,该函数将在元素进入或离开可视区域时被调用。回调函数接收两个参数:entries(一个包含所有被观察元素的交叉信息的数组)和 observer(观察者实例)。

其中 entries 值得一提,entries 是一个包含多个 IntersectionObserverEntry 对象的数组,每个对象代表一个观察的元素(target element)与根元素(root element)相交的信息。
IntersectionObserverEntry 对象包含以下属性:
intersectionRatio: 目标元素和根元素相交区域占目标元素总面积的比例,取值范围为 0 到 1。
intersectionRect: 目标元素和根元素相交区域的边界信息,是一个 DOMRectReadOnly 对象。
isIntersecting: 布尔值,表示目标元素是否正在与根元素相交。
rootBounds: 根元素的边界信息,是一个 DOMRectReadOnly 对象。
target: 被观察的目标元素,即当前 IntersectionObserverEntry 对象所对应的 DOM 元素。
time: 观察到的相交时间,是一个高精度时间戳,单位为毫秒。

function lazyLoadImages(selector, options) {
  const images = document.querySelectorAll(selector);

  const defaultOptions = {
    root: null,
    rootMargin: '0px',
    threshold: 0.1
  };

  const config = Object.assign({}, defaultOptions, options);

  const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        const image = entry.target;
        image.src = image.dataset.src;
        observer.unobserve(image);
      }
    });
  }, config);

  images.forEach((image) => {
    observer.observe(image);
  });
}

现在,你可以通过调用 lazyLoadImages 函数来懒加载指定选择器下的图片。函数接受两个参数:选择器和可选的配置对象。使用示例如下:

lazyLoadImages('.lazy', {
  threshold: 0.2
});

在上面的示例中,选择了所有带有 .lazy 类的图片进行懒加载,并修改了阈值为 0.2。

将图片懒加载逻辑封装成函数能够使代码更具可复用性和可维护性,便于在不同的项目中重复使用,并能更方便地进行配置和定制。

总结

       这是我在做项目时使用到的性能优化操作 — 图片懒加载,鉴于自身实力的有限,可能在文章讲解中出现错误,大家可以私信或评论指出错误。创作不易,点个赞呗。同时有任何疑问我们一起交流,一起成长。如果有更好的文章,也欢迎贴在下面哦,我们相互学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值