实现懒加载的几种方式(一)

1. 什么是懒加载?

当咱们碰到长网页有不少图片时,咱们会采用先加载出如今视口内的几张图片,当滚动条滚动到相应图片的位置时才去加载别的图片。这种延迟加载的方式咱们就称之为懒加载。html

2. 懒加载的优势

  • 提高用户体验

    假设一个场景:当咱们浏览淘宝的时候,页面须要加载很长时间才能显示出来,根据3秒钟定律,此时用户确定已经失去了耐心。可是使用懒加载就可以大大提高页面的展示速度,从而提高用户体验。git

  • 减轻服务器压力

    想象一下,若是一我的须要在短期内作不少事情,那这我的确定压力会很大。服务器也是同样的,咱们经过懒加载就减轻了服务器的工做量,让它有时间缓一缓,再来处理后面的事情。github

3. 实现原理

前面铺垫了这么多,下面重点来了(敲黑板!!!)。api

  • clientHeight:浏览器视口的高度;
  • scrollTop:滚动轴滚动的距离;
  • offsetTop:图片的头部距离浏览器顶部的高度(注意不是距离视口顶部的高度);

咱们实现懒加载的想法是一开始只加载显示在视口内的图片,从上图能够看出,咱们能够先只加载前两张图片。那么如何保证图片不加载出来呢?浏览器

能够经过将图片的地址保存在img元素的自定义属性上面,当须要加载的时候再将该自定义属性赋值给该图片的src性能优化

那么问题来了,何时加载后面的图片呢?bash

就是在咱们滚动滚动轴的时候,当下一张图片的顶部立刻要出如今视口的时候去加载下一张图片。服务器

好啦,如今咱们已经知道该什么去加载下一张图片了。那么接下来是第二个问题:怎么知道下一张图片立刻要出如今视口上了呢?dom

就是当图片距离浏览器顶部的高度---即offsetTop <= 视口高度clientHeight + 滚动条的长度scrollTop这是重点!!!明白了这个后面就简单了函数

最后一个问题,如何获取offsetTopscrollTopclientHeight这三个数值呢?

  • offsetTop:直接经过img.offsetTop就能够获取;
  • scrollTop:经过document.documentElement.scrollTop获取;
  • clientHeight:经过document.documentElement.clientHeight获取;

此处主要介绍懒加载,对于上述三个api不熟悉可自行百度学习。建议先记住他们能够这么获取就行。

4. 代码实现

  • 首先定义html结构和CSS样式;
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    img {
      height: 450px;
      display: block;
      margin-bottom: 20px;
    }
  </style>
</head>
<body>
  <!--图片地址暂时先保存在data-src这个自定义属性上面-->
  <img data-src="./img-loop/img/1.jpg" alt="懒加载1" />
  <img data-src="./img-loop/img/2.png" alt="懒加载2" />
  <img data-src="./img-loop/img/3.jpg" alt="懒加载3" />
  <img data-src="./img-loop/img/4.jpg" alt="懒加载4" />
  <img data-src="./img-loop/img/5.jpg" alt="懒加载5" />
</body>
</html>
复制代码
  • 下面编写js;
const imgs = document.getElementsByTagName('img');
    function lazyLoad(imgs) {
      // 视口的高度;
      const clientH = document.documentElement.clientHeight;
      // 滚动的距离,这里的逻辑判断是为了作兼容性处理;
      const clientT = document.documentElement.scrollTop || document.body.scrollTop;
      for(let i = 0; i < imgs.length; i++) {
        // 逻辑判断,若是视口高度+滚动距离 > 图片到浏览器顶部的距离就去加载;
        // !imgs[i].src 是避免重复请求,能够把该条件取消试试:能够看到不加该条件的话往回滚动就会重复请求;
        if(clientH + clientT > imgs[i].offsetTop && !imgs[i].src) {
          // 使用data-xx的自定义属性能够经过dom元素的dataset.xx取得;
          imgs[i].src = imgs[i].dataset.src;
        }
      }
    };
    // 一开始可以加载显示在视口中的图片;
    lazyLoad(imgs);
    // 监听滚动事件,加载后面的图片;
    window.onscroll = () => lazyLoad(imgs);
复制代码

至此,咱们就完成了开头gif图的懒加载的效果。

5. 性能优化

其实上面的代码仍是有不少性能优化的地方,好比说对于频繁触发的scroll事件会给浏览器形成很大的压力。咱们可使用节流函数作一个优化;

  • 没有优化前,滚动的时候lazyLoad函数频繁触发;

  • 使用节流函数进行优化;
// 设置节流函数
    function throttle(fn, delay) {
      let timer = null;
      return () => {
        if(timer) {
          return;
        };
        timer = setTimeout(() => {
          fn(imgs);
          timer = null;
        }, delay)
      }
    }
    // 监听滚动事件,加载后面的图片;
    window.onscroll = throttle(lazyLoad, 500);
复制代码
  • 优化后的效果;


完整代码

下一篇:懒加载的第二种实现方式

相关文章
相关标签/搜索