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

目录
  • 一.何为懒加载🌃:
  • 二.实现懒加载🌄:
    • 2.1 第一种方式:
    • 2.2 第二种方式:
    • 2.3 第三种方式(优):
  • 三.总结:

一.何为懒加载🌃:

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

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

二.实现懒加载🌄:

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

html:

    <img src="img/1.jpg" alt="xxx" />
    <img src="img/2.jpg" alt="xxx" />
    <img src="img/3.jpg" alt="xxx" />
    <img src="img/4.jpg" alt="xxx" />
    <img src="img/5.jpg" alt="xxx" />
    <img src="img/6.jpg" alt="xxx" />
    <img src="img/7.jpg" alt="xxx" />
    <img 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种方式,原理都是判断图片是否出现在可视区后给图片赋值src属性。

2.1 第一种方式:

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

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

此时页面效果如下,:

接下来用JavaScript实现当我们滚动滚动条时,如果图片出现在可视区,那么加载图片。加载图片其实就是给img标签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-src属性的值
          let trueSrc = i.getAttribute("data-src");
          //把值赋值给图片的src属性
          i.setAttribute("src", trueSrc);
      }
    }
  }
  //没发生滚动事件时也要先执行一次
  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 trueSrc = i.getAttribute("data-src");
            i.setAttribute("src", trueSrc);
          }
        }
      }
      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 时设置触发这个事件的图片的src属性值为data-src,开始加载。

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

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

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

完整代码:

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

效果如下,实现懒加载:

三.总结:

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

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

(0)

相关推荐

  • 快速实现JS图片懒加载(可视区域加载)示例代码

    js懒加载图片 如何提高网页加载速度?在网页中有许多img标签,这些标签就是图片,其属性src则是指向服务器地址,当浏览器从上往下读取到src标签中的地址时,浏览器就会开启线程,加载这张图片.而并不是等到整张页面都解析完成才加载图片.我们要做的就是加载用户可视范围内的图片. js懒加载图片的目的 1.网页优化,提高网页加载速度 2.页面优化友好,提高SEO收录与排名 3.提高用户体验,减少服务器压力 实例代码如下: <!DOCTYPE html> <html lang="en&

  • 原生JS实现图片懒加载(lazyload)实例

    前言 图片懒加载也是比较常见的一种性能优化的方法,最近在用vue做一个新闻列表的客户端时也用到了,这里就简单介绍下实现原理和部分代码. 实现原理 加载页面的时候,图片一直都是流量大头,针对图片的性能方法也挺多的比如base64.雪碧图等:懒加载也是其中一种,主要原理是将非首屏的图片src设为一个默认值,然后监听窗口滚动,当图片出现在视窗中时再给他赋予真实的图片地址,这样可以保证首屏的加载速度然后按需加载图片. 具体代码 首先在渲染时,图片引用默认图片,然后把真实地址放在data-*属性上面. <

  • js前端实现图片懒加载(lazyload)的两种方式

    在实际的项目开发中,我们通常会遇见这样的场景:一个页面有很多图片,而首屏出现的图片大概就一两张,那么我们还要一次性把所有图片都加载出来吗?显然这是愚蠢的,不仅影响页面渲染速度,还浪费带宽.这也就是们通常所说的首屏加载,技术上现实其中要用的技术就是图片懒加载--到可视区域再加载. 思路: 将页面里所有img属性src属性用data-xx代替,当页面滚动直至此图片出现在可视区域时,用js取到该图片的data-xx的值赋给src. 关于各种宽高: 页可见区域宽: document.body.clien

  • JavaScript实现图片懒加载的方法分析

    本文实例讲述了JavaScript实现图片懒加载的方法.分享给大家供大家参考,具体如下: 懒加载是非常实用的提升网页性能的方式,当访问一个页面的时候,只显示可视区域内的图片,其它的图片只有出现在可视区域内的时候才会被请求加载. 我们现在用原生的js实现简单的图片懒加载,主要利用的原理就是先不给设置src,而是把图片的路径放在data-src中,等待图片被加载的时候将路径取出放到src中. HTML代码 <div class="container"> <div clas

  • 深入研究jQuery图片懒加载 lazyload.js使用方法

    lazyload是一个用Javascript编写的jQuery插件,它可以延迟加载长页面中的图片,在浏览器可视区域外的图片将不会被载入,直到用户将它们滚动到它们所在的位置. 跟bootstrap一样,lazyload.js也是依赖于jQuery <script src="resources/js/jquery-1.8.3.min.js"></script> <script src="resources/js/jquery.lazyload.min

  • js实现图片懒加载效果

    本文实例为大家分享了js图片懒加载的具体代码,供大家参考,具体内容如下 图片懒加载,思路:当鼠标滑动到对应图片的高度时,进行图片的加载: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #div{ width: 575px; height: aut

  • 图片懒加载imgLazyLoading.js使用详解

    本文主要介绍web前端使用图片懒加载imgLazyLoading ,供大家参考,具体内容如下 1.html代码 //懒加载对象目标代码 <img originalSrc="__PUBLIC__/images/home/icon_pingtuan.png"> //引用本地js <script src="__PUBLIC__/js/imgLazyLoading.min.js"></script> <script src=&quo

  • 基于jquery的图片懒加载js

    以下是实现代码(基于jquery): 复制代码 代码如下: function lazyload(option){ var settings={ defObj:null, defHeight:0 }; settings=$.extend(settings,option||{}); var defHeight=settings.defHeight,defObj=(typeof settings.defObj=="object")?settings.defObj.find("img

  • JS图片预加载三种实现方法解析

    预加载基本概念:当页面打开图片提前加载,并且缓存在用户本地,需要用到时直接进行渲染:在浏览图片较多的网页(百度图库,淘宝京东等),可以有更好的用户体验: 一张图片的预加载 var img=new Image(); img.addEventListener("load",loadHandler); img.src="./img/1.jpg"; document.body.appendChild(img); console.log(img.width): functio

  • 前端图片懒加载(lazyload)的实现方法(提高用户体验)

    定义 图片懒加载又称图片延时加载.惰性加载,即在用户需要使用图片的时候加载,这样可以减少请求,节省带宽,提高页面加载速度,相对的,也能减少服务器压力. 惰性加载是程序人性化的一种体现,提高用户体验,防止一次性加载大量数据,而是根据用户需要进行资源的请求. 实现 懒加载的难点在于确定某张图片是否是用户需要的资源,在浏览器中,用户需要的是可视区内的资源,因此我们只需要判断图片是否已经呈现在可视区内,当图片呈现在可视区内时,获取图片的真实地址并赋给该图片即可(图片宽高需要指定,可以利用padding处

  • 前端JS图片懒加载原理方案详解

    目录 背景 原理 方案 方案一:img的loading属性设为“lazy” 使用方法 优点 兼容性 缺点 方案二:通过offsetTop来计算是否在可视区域内 优化 优点 缺点 方案三:通过getBoundingClientRect来计算是否在可视区域内 方案四:使用IntersectionObserver来判断是否在可视区域内 兼容性 优点 缺点 问题 布局抖动 响应式图片 SEO不友好 插件 背景 懒加载经常出现在前端面试中,是前端性能优化的常用技巧.懒加载也叫延迟加载,把非关键资源先不加载

  • 浅谈vue中使用图片懒加载vue-lazyload插件详细指南

    在vue中使用图片懒加载详细指南,分享给大家.具体如下: 说明 当网络请求比较慢的时候,提前给这张图片添加一个像素比较低的占位图片,不至于堆叠在一块,或显示大片空白,让用户体验更好一点. 使用方式 使用vue的 vue-lazyload 插件 插件地址:https://www.npmjs.com/package/vue-lazyload 案例 demo: 懒加载案例demo Installation 安装方式 npm $ npm i vue-lazyload -D CDN CDN: https:

  • JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)

    目录: 懒加载的意义(为什么要使用懒加载) 原理 代码 在上篇文章给大家介绍了JavaScript实现图片懒加载(Lazyload),大家可以参考下. 懒加载的意义(为什么要使用懒加载) 对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小,而代码也许就只有几十KB.当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载完成,也许会失去很多的用户. 所以,对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区

  • angular实现图片懒加载实例代码

    这两天一直纠结angular的图片懒加载插件中无法自拔.在使用过程深深感到js学艺不精的痛苦,想修改源码又不会修改,只能尽力压榨如何使用插件上.这里主要谈谈在使用插件的过程遇到的一些问题. 一)我使用的是angular-imglazyload这个插件.[https://www.npmjs.com/package/angular-imglazyload]主要是这个插件小不依赖jquery库,然后下载源码运行成功后,我就整合到自己项目上运行,结果发现竟然只有前2张加载了,滚动了都没有反映.下面是我的

随机推荐