懒加载预加载

发布于:2025-03-07 ⋅ 阅读:(21) ⋅ 点赞:(0)

(一)、懒加载

1.什么是懒加载?

懒加载也就是延迟加载。当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次,俗称占位图),

只有当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来。这就是图片懒加载。

2.为什么要使用懒加载?

很多页面,内容很丰富,页面很长,图片较多。比如说各种商城页面。这些页面图片数量多,而且比较大,少说百来K,多则上兆。要是页面载入就一次性加载完毕。估计大家都会等到黄花变成黄花菜了。

3.懒加载的优点是什么?

页面加载速度快、可以减轻服务器的压力、节约了流量,用户体验好

4.懒加载的原理是什么?

页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片,只有通过javascript设置了图片路径,浏览器才会发送请求。

懒加载的原理就是先在页面中把所有的图片统一使用一张占位图进行占位,把真正的路径存在元素的“data-url”(这个名字起个自己认识好记的就行)属性里,要用的时候就取出来,再设置;

5.懒加载的实现步骤?

1)首先,不要将图片地址放到src属性中,而是放到其它属性(data-original)中。

2)页面加载完成后,判断图片是否在用户的视野内,如果在,则将data-original属性中的值取出存放到src属性中。

6、懒加载实现方式

html结构

1、 obj.getAttribute("属性名")通过元素节点的属性名称获取属性的值。

2、使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放, dataset 获取自定义属性值的使用

<ul>
    <li>
      <img data-src="./img/img1.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img2.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img3.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img4.gif" src="./img/loading.gif" alt="" />
    </li>
    <li>
      <img data-src="./img/img5.png" src="./img/loading.gif" alt="" />
    </li>
  </ul>
第一种

元素距顶部的高度 - 页面被卷去的高度 <= 浏览器可视区的高度)

来判断是否符合我们想要的条件.需要实时监听页面滚动时 图片的高度变化

<script>
        window.onload = function () {
          var imgs = document.querySelectorAll("img");
          // 初始化执行
          lazyLoad(imgs);
          // 滚动执行
          window.addEventListener("scroll", function () {
            lazyLoad(imgs);
          });
  
          function lazyLoad(imgs) {
            for (let i = 0; i < imgs.length; i++) {
              var imgoffsetT = imgs[i].offsetTop; // 图片的距顶部的高度
              var wheight = window.innerHeight; // 浏览器可视区的高度
              var scrollT = document.documentElement.scrollTop; // 页面被卷去的高度
              if (imgoffsetT - scrollT <= wheight) {
                // 判断图片是否将要出现
                imgs[i].src = imgs[i].dataset.src; // 出现后将自定义地址转为真实地址
              }
            }
          }
        };
      </script>
第二种

getBoundingClientRect()

——获取元素位置,这个方法没有参数

——用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。

——是DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。

该函数返回一个Object对象,该对象有6个属性:top,lef,right,bottom,width,height;

window.onload = function () {
  var imgs = document.querySelectorAll("img");
  // 初始调动一次
  lazyLoad();
  // 监听滚动时,再调用函数
  window.addEventListener("scroll", throttle(lazyLoad, 1000), false);


  //函数1:封装判定图片是否在可视区
  function isInVisibleArea(imgOne) {
    const info = imgOne.getBoundingClientRect();
    //  获取页面可视区的高度,宽度
    let windowH = window.innerHeight;
    let windowW = window.innerWidth;
    // 限定参数在可视区内
    let res = info.bottom > 0 && info.top < windowH && info.right > 0 && info.left < windowW;
    return res;
  }

  //函数2: 封装滚动时重新加载函数
  function lazyLoad() {
    for (let i = 0; i < imgs.length; i++) {
      const imgOne = imgs[i];
      // 判定是否在可视区内
      if (isInVisibleArea(imgOne)) {
        // 替换src方法一:
        // imgOne.src = imgOne.getAttribute("data-src");
        // 替换src方法二:
        imgOne.src = imgOne.dataset.src;
        // imgs.splice(i,1)
        // i--;
      }
      console.log("我滚了"); //滚动就出发,要做节流操作
    }
  }

  //函数3:节流函数
  function throttle(fn, time = 250) {
    let lastTime = null;
    return function (...args) {
      const now = Date.now(); //当前时间
      if (now - lastTime >= time) {
        fn(); //帮助执行函数,改变上下文
        lastTime = now;
      }
    };
  }
};
第三种

IntersectionObserver(callback)

callback函数会触发两次,元素进入视窗(开始可见时)和元素离开视窗(开始不可见时)都会触发

<script>
        const imgs = document.querySelectorAll("img");
        var callback = function (res) {
          //res 是观察的元素数组   info 每个被观察的图片信息
          res.forEach(function (info) {
            //  isIntersecting 目标是否被观察到,返回布尔值
            if (info.isIntersecting) {
              // img 就是当前的图片标签
              const img = info.target;
              img.src = img.getAttribute("data-src");
              // 真实地址替换后 取消对它的观察
              obs.unobserve(img);
             // console.log("触发");
            }
          });
        };
  
        // 实例化 IntersectionObserver
        const obs = new IntersectionObserver(callback);
        // 遍历imgs所有的图片,然后给每个图片添加观察实例
        imgs.forEach(function (img) {
          //  observe : 被调用的IntersectionObserver实例。给每个图片添加观察实例
          obs.observe(img);
        });
      </script>

(二)、预加载

1.什么是预加载

资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。预加载简单来说就是将所有所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。

2.为什么要用预加载

在网页全部加载之前,对一些主要内容进行加载,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,直到所有内容加载完毕。

3、预加载实现方式

html结构

<!-- 需求:实现点击图片,切换下一张图片 -->
    <div>
      <p></p>
      <img src="./img/img1.gif" alt="" />
    </div>

js实现

<script>
      const imgs = ["./img/img2.gif", "./img/img3.gif", "./img/img4.gif", "./img/img5.png"];
      const img = document.querySelector("img");
      const test = document.querySelector("p");
      //实现点击切换下一张图片
      let index = 0;
      test.innerHTML = "我是第" + (index + 1) + "张图片";
      img.addEventListener("click", function () {
        if (index < imgs.length) {
          img.src = imgs[index];
          index++;
          test.innerHTML = "我是第" + (index + 1) + "张图片";
        }else{
          alert('没有了')
        }

        // 切换图片后,同时让浏览器提前加载下载一张图片
        if (index < imgs.length) {
          preLoad(imgs[index]);
        }
      });

      // 调用加载函数,页面一开始就加载数组第一个元素
      preLoad(imgs[0]);
      
      // 封装函数,新建一个img标签,然后增加src属性,让浏览器加载下一张图片
      function preLoad(src) {
        img.addEventListener("load", () => {
          // 创建一个新的img标签
          const img = document.createElement("img");
          // 给img添加src属性,为我们传进来的src
          img.src = src;
        });
      }
    </script>