前端架构&软实力复习-图片预加载&懒加载

2021-05-27 10:17:462021-05-27 18:42:04

预加载

new一个新的Image,给Imagesrc赋值为真正的src;该Image在加载完毕后相应的图片资源就会在本地缓存

懒加载

首先设置一个把src设置为临时的data-src属性,src设置为一个loading图,待当前元素出现在视口后用data-src替换src

可供实现的方案:

  • window.onscroll(节流) + clientTop + offsetTop + clientHieght + scrollTop

    不容易判断元素位置

  • widnow.onscroll(节流) + Element.getBoundingClientRect()

    getBoundingClientRect()会触发回流

  • IntersectionObserver + polyfill

  • imglazy属性

    兼容性差

IntersectionObserver为实现方案:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div style="height: 100vh;"></div>
  <img id="img" data-src="https://mrrsblog.oss-cn-shanghai.aliyuncs.com/avatar.jpg" alt="" srcset="">
  <script>
    const observer = new IntersectionObserver((changes) => {
      changes.forEach((change) => {
        if (change.isIntersecting) {
          const img = change.target;
          img.src = img.dataset.src;
          Reflect.deleteProperty(img.dataset, 'src');
          observer.unobserve(img);
        }
      })
    });
    observer.observe(document.querySelector('#img'));
  </script>
  <script>
      // todo 添加节流
     window.addEventListener('scroll', () => {
      const innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
      const img = document.querySelector("#img");
      console.log(img.dataset.src);
      const { left, right, top, bottom } = img.getBoundingClientRect();
      if (innerHeight > top && bottom > -30) {
        img.src = img.dataset.src;
        Reflect.deleteProperty(img.dataset, 'src');
      }
    })
  </script>
</body>
</html>