记录折腾的那点事
在折腾的道路上永不止步

前端性能优化-图片懒加载(防抖、节流

首先 小学生在这里 祝大家 元旦快乐!!!!!

懒加载使用场景

在一些图片量比较大的场景(电商首页,小程序首页等),如果我们打开页面时就加载所有的图片,那势必会导致页面的卡顿以及白屏,给用户不好的体验,导致用户流失。

但是我们仔细想一下,用户真的需要我们显示所有图片一起展示吗?其实并不是,用户看到的只是浏览器可视区域的内容。所以从这个情况我们可以做一些优化,只显示用户可视区域内的图片,当用户触发滚动的瞬间再去请求显示给用户。

懒加载的思路

  • img 标签有自定义属性 data-src
  • 首屏展示可视区域内的图片 src 值 替换为 data-src
  • 滚动出现在可视区域的图片即时展示 (重复第二步)

懒加载的实现

<style>  html,  body {  width: 100%;  height: 100%;  }  .containr {  width: 100%;  height: 100%;  overflow-y: auto;  }  .img {  width: 100%;  height: 300px;  }  .pic {  width: 100%;  height: 300px;  } </style> <div class="containr"> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/1.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/2.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/3.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/4.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/5.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/6.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/7.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/8.png"> </div> <div class="img"> <img class="pic" src="" alt="" data-src="./imgs/9.png"> </div> </div> <script>  // 获取所有图片的数组  const imgs = document.querySelectorAll('.containr .pic')  // 获取父元素  const containr = document.querySelector('.containr')  // 获取可视区域高度  const viewHeight = window.innerHeight    const load = lazyLoad()  // 首屏渲染  load()  function lazyLoad() {  // 运用闭包 count 进行计数 避免已显示的图片重复参与循环  let count = 0  return () => {  for (let i = count; i < imgs.length; i++) {  // getBoundingClientRect()获取返回元素的大小及其相对于视口的位置  // 获取第i张图片是否在可视区域  let distance = viewHeight - imgs[i].getBoundingClientRect().top  if (distance >= 0) {  // 图片在可视区域时设置图片的src 为 当前元素 data-src  imgs[i].src = imgs[i].getAttribute('data-src')  // 图片已被显示,下次从count + 1 张开始检查是否在可视区域  count += 1  }  }  }  }  // 添加滚动事件触发加载  containr.addEventListener('scroll', load, false) </script> 复制代码

至此我们已经初步完成了我们的懒加载,但是我们大家都知道,scroll这个事件实在太容易被触发了,用户一滚动鼠标就会触发很多次,如果一直滚势必会导致重复触发执行我们的事件,这也会导致我们的性能急剧下降,所以这就引出了我们的混合体 防抖节流 来优化我们的性能。

防抖 && 节流

防抖:在一定时间内,触发多次事件,只认第一次触发的,到了时间结束执行事件

function throttle(fn, time) { let oldTime = 0,
                timer = null; return () => { const nowTime = new Date() if (nowTime - oldTime >= time) {
                   fn()
                   oldTime = nowTime
                }
            }
        }
复制代码

节流:在一定时间内,触发多次事件,只认最后一次触发的并且重置时间,到了时间结束执行事件

function debounce(fn, time) { let timer = null return () => { if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    fn()
                }, time);
            }
        }
复制代码

在这里debounce有一个严重的问题就是如果用户一直触发事件,用户会一直得不到响应,所以我们可以借助防抖的思路来优化节流。

function debounce(fn, time) { let oldTime = 0,
                timer = null; return () => { const nowTime = new Date() if (nowTime - oldTime < time) { if (timer) {
                        clearTimeout(timer)
                    }
                    timer = setTimeout(() => {
                        oldTime = nowTime
                        fn()
                    }, time);
                } else { // 用户重复触发,到达事件节点 还是会去执行事件   oldTime = nowTime  fn()  }  }  } 复制代码

所以最后我们监听事件可以修改为containr.addEventListener(‘scroll’, debounce(load, 1000), false),这就完美达到了我们优化的目的。

赞(0)
未经允许不得转载:ghMa » 前端性能优化-图片懒加载(防抖、节流
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址