图片的懒加载和预加载

在这里插入图片描述

1. 懒加载


1.1 懒加载的介绍

1️⃣ 什么是懒加载?

懒加载也叫作延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。

当访问一个页面的时候,先把 img 元素或者其它元素的背景图片路径设置成本地默认图片(充当占位图,减少请求次数),可视区域外的图像不会加载,只有当图片出现在浏览器的可视区域内时,才设置图片的真正路径,让图片显示出来。


2️⃣ 为什么要使用懒加载?

✔ 提升用户体验:比如像在淘宝、京东这种有大量图片的网页中,如果所有图片都一起加载,会导致用户的等待时间,严重影响了用户体验。

✔ 提升页面加载速度:分批加载图片可以提升页面的加载速度。

✔ 减轻服务器的压力:分批加载图片也能够减轻服务器的压力。


1.2 懒加载的原理

首先将图片的 src 属性值设为空字符串,图片的真实路径设置在自定义属性 data-xxx中,并且监听页面滚动 scroll 事件,判断图片是否进入可视区域,当图片进入可视区域时,就设置图片的 src 属性值为 data-xxx 的值。


1.3 懒加载的实现

实现懒加载需要知道元素对于视口的位置表示方法。如图所示:

在这里插入图片描述

当图片满足 top < H && bottom > 0 条件时,就可以认为在可视区域内:

在这里插入图片描述

.image-item {
  display: block;
  margin-bottom: 50px;
  height: 200px;
}
<body>
  <div class="lazyLoad">
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png"
    />
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/5cfc7b6a04e845aa9fe1e9c6968df8d3.png"
    />
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/ac97b2b86b0c4829ad328ca947742e6c.png"
    />
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/4297a45efc6a4aab833a3ec50505f61e.png"
    />
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/5ab835374e9746c8ad7a5b42cb22ffdc.png"
    />
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/a7cc370c82f441c5a8ee386290e06d59.png"
    />
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/346190fed3a541d38697ecef92adbcac.png"
    />
    <img
      class="image-item"
      data-src="https://img-blog.csdnimg.cn/76987a5ca66c4704b7744c6f120baf51.png"
    />
  </div>
  <script>
    var viewHeight = document.documentElement.clientHeight; // 可视区域高度
    var loadArr = []; // 存储已被加载过的图片的索引号(index),之后只遍历没被加载过的图片。

    // 懒加载函数
    function lazyLoad() {
      // 把类数组转成数组
      var eles = Array.from(document.querySelectorAll(".image-item"));

      // 过滤掉已加载过的图片
      var newEles = eles.filter((v, i) => {
        return loadArr.every((x) => {
          return x !== i;
        });
      });

      for (var j = 0; j < newEles.length; j++) {
        let position = newEles[j].getBoundingClientRect();

        if (position.bottom >= 0 && position.top < viewHeight) {
          newEles[j].src = newEles[j].getAttribute("data-src");
          loadArr.push(eles.indexOf(newEles[j]));
        }
      }
    }
    
    lazyLoad(); // 刚开始还没滚动屏幕,要先触发一次函数,初始化首页的页面图片

    window.onscroll = lazyLoad;
  </script>
</body>

🚀 使用节流函数进行性能优化

如果直接将懒加载函数绑定到 scroll 事件上,当页面滚动时,函数会被高频率触发,这会非常影响性能。

节流:如果持续触发事件,每隔一段时间才执行一次事件。

// 代码差异

// 节流函数(有头有尾)
// fun:要节流的函数,time:多少秒执行一次
function debounce(fun, time) {
  var timeout;
  var flag = true;

  return function () {
    var _this = this;
    var args = arguments;

    if (!timeout) {
      timeout = setTimeout(function () {
        fun.apply(_this, args);
        timeout = null;
      }, time);
    }

    if (flag) {
      // 实现有头
      fun.apply(_this, args);
      flag = false;
    }
  };
}

window.addEventListener("scroll", debounce(lazyLoad, 500));

2. 预加载


2.1 预加载的介绍

1️⃣ 什么是预加载?

预加载就是将所需的资源提前请求加载到本地,这样后面在需要用到的时候就直接从缓存读取资源。


2️⃣ 为什么要使用预加载?

对网页的图片内容进行预加载,保证了图片快速、无缝的加载,以提供更好的用户体验,减少等待时间。


2.2 预加载的实现


2.2.1 使用纯 CSS 实现

使用 CSS 的 background 属性将图片加载,设置容器的宽高,使图片不显示出来。但是这些图片会跟随文档一起加载,所以会影响页面的加载速度。

body:after {
  content: "";
  display: block;
  width: 0;
  background: url("https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png"),
    url("https://img-blog.csdnimg.cn/5cfc7b6a04e845aa9fe1e9c6968df8d3.png"),
    url("https://img-blog.csdnimg.cn/ac97b2b86b0c4829ad328ca947742e6c.png");
}

2.2.2 CSS + JS

为了解决第一个方法提到的影响页面加载速度的问题,可以通过 window.onload 事件推迟预加载时间,直到页面加载完毕才去预加载图片。

var preloadImgArr = [
  "https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png",
  "https://img-blog.csdnimg.cn/5cfc7b6a04e845aa9fe1e9c6968df8d3.png",
  "https://img-blog.csdnimg.cn/ac97b2b86b0c4829ad328ca947742e6c.png",
];

// 预加载函数
function preloadImg(list) {
  if (document.getElementById) {
    var bodyEl = document.getElementsByTagName("body")[0];

    for (let i = 0; i < list.length; i++) {
      let el = document.createElement("div");
      el.style.width = 0;
      el.style.background = `url(${list[i]})`;
      bodyEl.appendChild(el);
    }
  }
}

function addLoadEvent(fun, list) {
  var oldOnload = window.onload; // 存储原生的 onload 事件

  // 判断其它库是否改写了 onload 方法
  if (typeof window.onload !== "function") {
    // 其它库未改写 onload 方法
    window.onload = function () {
      fun(list);
    };
  } else {
    window.onload = function () {
      // 若其它库改写了 onload,则先执行其它库的 onload 方法,再执行 fun
      if (oldOnload) {
        oldOnload();
      }

      fun(list);
    };
  }
}

addLoadEvent(preloadImg, preloadImgArr);

2.2.3 new Image()

function preload() {
  for (let i = 0; i < arguments.length; i++) {
    new Image().src = arguments[i];
  }
}

preload(
  "https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png",
  "https://img-blog.csdnimg.cn/76987a5ca66c4704b7744c6f120baf51.png"
);

2.2.4 使用 Ajax 实现

window.onload = function () {
	setTimeout(function () {
		// 预加载 js
		var xhr = new XMLHttpRequest();
		xhr.open('GET', 'xxx');
		xhr.send(null);

		// 预加载 css
		xhr = new XMLHttpRequest();
		xhr.open('GET', 'xxx');
		xhr.send(null);
		
		// 预加载 img
		new Image().src = 'xxx';
	})
}

3. 懒加载和预加载的对比

1️⃣ 两者行为是相反的,一个是提前加载,一个是延迟加载。

2️⃣ 懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端的压力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值