我的编程空间,编程开发者的网络收藏夹
学习永远不晚

前端必会的图片懒加载(三种方式)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

前端必会的图片懒加载(三种方式)

一.何为懒加载🌃:

  在我们访问一个图片展示比较多的网页时,加载速度慢很多时候正是因为图片多导致,大量的img图片导致页面渲染的堵塞。当费了许多力气把全部图片和页面加载出来时而用户早已离去。另一方面,若用户只查看了网页的前面部分便离开,许多已经加载却因为处于网页底部而未呈现在视口区的图片,它们极大加重服务器压力了但是用户看都没看,白白浪费了性能。

  为了解决上面的问题需要引入图片懒加载,懒加载其实很好理解,重点就是一个‘懒'字。当用户滚动相应可视区域,若可视区域有图片便加载,而在可视区域外未加载过的图片它们先不加载,如果用户滚动可视区域到它们时它们再加载,否则一律不加载。这样一来就大大提高了网页渲染的性能和减少不必要的浪费。

二.实现懒加载🌄:

  首先,先定义一个基本的HTML页面模拟一些存在大量图片的网页,比如我用8个img 标签来模拟,同时定义一些基本css样式,代码与初始效果如下:

html:


    <img class="lazy" data-src="img/1.jpg" alt="xxx" />
    <img class="lazy" data-src="img/2.jpg" alt="xxx" />
    <img class="lazy" data-src="img/3.jpg" alt="xxx" />
    <img class="lazy" data-src="img/4.jpg" alt="xxx" />
    <img class="lazy" data-src="img/5.jpg" alt="xxx" />
    <img class="lazy" data-src="img/6.jpg" alt="xxx" />
    <img class="lazy" data-src="img/7.jpg" alt="xxx" />
    <img class="lazy" data-src="img/8.jpg" alt="xxx" />

css:


 * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      img {
        width: 500px;
        height: 300px;
        object-fit: cover;
        margin: 20px;
      }
      body {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-evenly;
      }

初始效果如下,可以看到右边的控制台,8张图片在我一运行这个页面的时候就都一同被加载渲染了:

在这里插入图片描述  

下面是利用JavaScript实现懒加载的3种方式,原理都是判断图片是否出现在可视区后给图片赋值class="lazy" data-src属性。

2.1 第一种方式:

  首先,修改每一个img标签,利用HTML提供的 data- 属性来嵌入自定义数据,这个自定义数据我们存放这个标签原本的图片地址。同时,全部的图片的class="lazy" data-src属性我们都用一张同样的图表示,这个图一般可为显示载入中字样的图片。注意,如果多个img标签class="lazy" data-src引用的是同一张图片,那么只会加载一次,不会多次加载,所以我下面给每个图class="lazy" data-src定义同一张图。


    <img data-class="lazy" data-src="img/1.jpg" class="lazy" data-src="img/0.png" alt="xxx" />
    <img data-class="lazy" data-src="img/2.jpg" class="lazy" data-src="img/0.png" alt="xxx" />
    <img data-class="lazy" data-src="img/3.jpg" class="lazy" data-src="img/0.png" alt="xxx" />
    <img data-class="lazy" data-src="img/4.jpg" class="lazy" data-src="img/0.png" alt="xxx" />
    <img data-class="lazy" data-src="img/5.jpg" class="lazy" data-src="img/0.png" alt="xxx" />
    <img data-class="lazy" data-src="img/6.jpg" class="lazy" data-src="img/0.png" alt="xxx" />
    <img data-class="lazy" data-src="img/7.jpg" class="lazy" data-src="img/0.png" alt="xxx" />
    <img data-class="lazy" data-src="img/8.jpg" class="lazy" data-src="img/0.png" alt="xxx" />

此时页面效果如下,:

在这里插入图片描述

接下来用JavaScript实现当我们滚动滚动条时,如果图片出现在可视区,那么加载图片。加载图片其实就是给img标签class="lazy" data-src属性赋值为本来的地址,那么此时图片便会请求加载渲染出来。


 //获取全部img标签
var images = document.getElementsByTagName("img");

 window.addEventListener("scroll", (e) => {
    //当发生滚动事件时调用ergodic事件
    ergodic();
  });
  function ergodic() {
    // 遍历每一张图
    for (let i of images) {
      //判断当前图片是否在可视区内
      if (i.offsetTop <= window.innerHeight + window.scrollY) {
          //获取自定义data-class="lazy" data-src属性的值
          let trueclass="lazy" data-src = i.getAttribute("data-class="lazy" data-src");
          //把值赋值给图片的class="lazy" data-src属性
          i.setAttribute("class="lazy" data-src", trueclass="lazy" data-src);
      }
    }
  }
  //没发生滚动事件时也要先执行一次
  ergodic();

 其中, offsetTop 为元素距离顶部的距离;window.innerHeight 为当前窗口的高度;window.scrollY 为滚动距离;不难知道,当 i.offsetTop <= window.innerHeight + window.scrollY时图片就处于窗口可视区了。

此时效果如下,观察右侧控制台,发现当滚动时图片才加载:

在这里插入图片描述

2.2 第二种方式:

第二种方式其实和第一种差不多,只是计算图片是否在可视区方式不同,重复的部分就省略了,如下:


  window.addEventListener("scroll", (e) => {
        ergodic();
      });
      function ergodic() {
        for (let i of images) {
          //计算方式和第一种方式不同
          if (i.getBoundingClientRect().top < window.innerHeight) {
            let trueclass="lazy" data-src = i.getAttribute("data-class="lazy" data-src");
            i.setAttribute("class="lazy" data-src", trueclass="lazy" data-src);
          }
        }
      }
      ergodic();

 其中,getBoundingClientRect().top 为元素相对于窗口的位置;window.innerHeight 为当前窗口的高度;当元素对于窗口的位置小于当前窗口的高度时,那自然处于了窗口可视区了。

效果一样的:

在这里插入图片描述

2.3 第三种方式(优):

 其实上面两种方式已经大致实现懒加载,但是,它们都有一个缺点,就是一当发生滚动事件时,就发生了大量的循环和判断操作判断图片是否可视区里。这自然是不太好的,那是否有解决方法。这里就引入了一个叫 Intersection Observer 观察器接口,它是是浏览器原生提供的构造函数,使用它能省到大量的循环和判断。当然它的兼容可能不太好,看情况使用。

 Intersection Observer 是什么呢?这个构造函数的作用是它能够观察可视窗口与目标元素产生的交叉区域。简单来说就是当用它观察我们的图片时,当图片出现或者消失在可视窗口,它都能知道并且会执行一个特殊的回调函数,我们就利用这个回调函数实现我们的操作。概念枯燥难懂,直接看下面例子:

1.既然IntersectionObserver是浏览器原生提供的构造函数,先new一个实例:


 const observer = new IntersectionObserver(callback);

 其中它会有一个参数callback,参数为一个回调函数,当目标元素能看见会触发一次,目标元素看不见会再触发一次。

2.使用实例通过observer属性可以为每一张图片绑定一个观察器:


for (let i of images) {
        observer.observe(i);
      }

3.由上可以知道每张图片能看见会和看不见时都会触发一次callback回调函数,同时callback这个回调函数也有一个参数entries,我们可以运行触发这个回调函数看看它是什么:


 function callback(entries) {
      console.log(entries)
      }

在这里插入图片描述

 可以看到每次图片能看见会和看不见时都会触发一次callback回调函数,并输出了参数entries的内容。其实,entries为一个数组,而它的数组元素为当前改变了状态触发了事件的目标元素。其中有一个isIntersecting属性,当目标元素在视口看得见为它true,不在时它为 false 。我们就可以利用这个属性,当它为 true 时设置触发这个事件的图片的class="lazy" data-src属性值为data-class="lazy" data-src,开始加载。


function callback(entries) {
        for (let i of entries) {
          if (i.isIntersecting) {
              let img = i.target;
              let trueclass="lazy" data-src = img.getAttribute("data-class="lazy" data-src");
              img.setAttribute("class="lazy" data-src", trueclass="lazy" data-src);
          }
        } 
      }

 其中 target 事件属性返回触发事件的元素。当前,当回来滚动时,图片会一会可见一会不可见,它都是触发回调函数,所以当某图片已经加载时我们要停掉它的观察器。利用unobserve属性可停掉。


  function callback(entries) {
    for (let i of entries) {
      if (i.isIntersecting) {
          let img = i.target;
          let trueclass="lazy" data-src = img.getAttribute("data-class="lazy" data-src");
          img.setAttribute("class="lazy" data-src", trueclass="lazy" data-src);
          // 结束观察
          observer.unobserve(img);
      }
    } 
  }

完整代码:


 var images = document.getElementsByTagName("img");
   function callback(entries) {
    for (let i of entries) {
      if (i.isIntersecting) {
          let img = i.target;
          let trueclass="lazy" data-src = img.getAttribute("data-class="lazy" data-src");
          img.setAttribute("class="lazy" data-src", trueclass="lazy" data-src);
          observer.unobserve(img);
      }
    } 
  }
      const observer = new IntersectionObserver(callback);
      for (let i of images) {
        observer.observe(i);
      }

效果如下,实现懒加载:

在这里插入图片描述

三.总结:

  以上就为实现图片懒加载的全部内容啦。✨总的来说就是某些存在大量的img的网页如果页面渲染阶段就把图片全部加载,那会导致页面渲染的堵塞。为了解决引入图片懒加载,用户滚动相应可视区域,若可视区域有图片那么该图片才加载。其中核心就是给图片定义自定义属性data-class="lazy" data-src存放图片真的访问地址,当图片出现在可视区时才将data-class="lazy" data-src的值赋值给class="lazy" data-src属性,此时图片便加载。其中不止不可通过一些常见属性判断图片位置,还引入了IntersectionObserver观察器接口更少消耗的实现懒加载。

到此这篇关于前端必会的图片懒加载(三种方式)的文章就介绍到这了,更多相关图片懒加载内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

前端必会的图片懒加载(三种方式)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

前端图片懒加载的原理与3种实现方式举例

图片懒加载又称图片延时加载、惰性加载,即在用户需要使用图片的时候加载,这样可以减少请求,节省带宽,提高页面加载速度,相对的,也能减少服务器压力,下面这篇文章主要给大家介绍了关于前端图片懒加载的原理与3种实现方式的相关资料,需要的朋友可以参考下
2023-03-01

web前端图片懒加载的原理与实现方式有哪些

这篇文章主要讲解了“web前端图片懒加载的原理与实现方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“web前端图片懒加载的原理与实现方式有哪些”吧!一. 图片懒加载的目的大型网站如常
2023-07-05

vue3 图片懒加载的两种方式、IntersectionObserver和useIntersectionObserver实例详解

这篇文章主要介绍了vue3 图片懒加载的两种方式、IntersectionObserver和useIntersectionObserver实例详解,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
2023-03-19

Tensorflow 2.4加载处理图片的三种方式详解

这篇文章主要为大家介绍了Tensorflow 2.4加载处理图片的三种方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-21

详解三种Javascript图片预加载的方法

预加载图片是提高用户体验的一个很好方法。图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度。

jQuery+CSS怎样实现前端网页加载进度条的三种方式

这篇“jQuery+CSS怎样实现前端网页加载进度条的三种方式”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“jQuery+CSS怎样实现前端网页加载进度条的三种方式”,小编整理了以下知识点,请
2023-06-06

编程热搜

目录