图片懒加载&&防抖节流

为什么要懒加载

对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小,而代码也许就只有几十KB。当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载完成,也许会失去很多的用户。

所以,对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载。这样子对于页面加载性能上会有很大的提升,也提高了用户体验。

懒加载的原理

当图片不在可视区域内时,统一设置imgsrc为指定图片src='default.png',添加data-src(自定义属性)属性指向真实图片url

<img src='default.png' data-src='httt://www.xxx.com/images/001.jpg'>
复制代码

监听scroll事件,当图片出现在可视区时,提取data-src的值并赋给src,加载真正图片

实现代码

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        img {
            display: block;
            margin-bottom: 50px;
            width: 400px;
            height: 400px;
        }
    </style>
</head>
<body>
    <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
    <img src="default.jpg" data-src="https://img1.baidu.com/it/u=3662100061,2823755293&fm=26&fmt=auto&gp=0.jpg" alt="">
    <img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt="">
    <img src="default.jpg" data-src="https://img0.baidu.com/it/u=3290460621,176418012&fm=15&fmt=auto&gp=0.jpg" alt="">
    <img src="default.jpg" data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdata.useit.com.cn%2Fuseitdata%2Fforum%2F201604%2F01%2F102512cgszscmpyq9xmd2i.jpg&refer=http%3A%2F%2Fdata.useit.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628316865&t=f24fed6c4dcc33aefdd3e836c863733f" alt="">
    <img src="default.jpg" data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20180420%2Ff28943a3df704463abdd923478b40d08.png&refer=http%3A%2F%2F5b0988e595225.cdn.sohucs.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628316865&t=4b4eed09d9384fb51c56b79a238d7cde" alt="">
    <script>
        let sHeight = null
        window.onscroll = lazyLoad
        function lazyLoad(){
            document.querySelectorAll("img").forEach(item=>{
                sHeight = document.body.clientHeight
                if( item.getBoundingClientRect().top <  sHeight && item.attributes.src.value === "default.jpg" ){
                    item.attributes.src.value = item.attributes["data-src"].value
                }
            })
        }
        lazyLoad()
    </script>
</body>

 通过浏览器加载资源查看是否达到预期效果

还没完,lazyLodescorll事件绑定会导致高频触发,这只会增加浏览器的压力,违背了我们的初衷,所以我们需要限制事件频率,改良代码如下

    <script>
        let sHeight = null
        window.onscroll = debound(lazyLoad, 800)
        //window.onscroll = debound(lazyLoad, 2000)
        function lazyLoad(){
            document.querySelectorAll("img").forEach(item=>{
                sHeight = document.body.clientHeight
                if( item.getBoundingClientRect().top <  sHeight && item.attributes.src.value === "default.jpg" ){
                    item.attributes.src.value = item.attributes["data-src"].value
                }
            })
        }
        lazyLoad()
        function debound(fn, wait) {
            let timeOut = null
            return function (){
                clearTimeout(timeOut )
                timeOut = setTimeout(()=>{
                    fn()
                }, wait)
            }
        }

    </script>

debounce函数限制了lazyLoad的触发频率,800ms等待时间内scroll时间再次触发则重置时间,术语叫防抖。这就完了?nonono!假设我们把wait设的大点,2s,如果用户一直滑动滚动条,时间不断被重置,造成的效果是lazyLoad一直不被执行,图片加载不出来,这是不能接受的,所以我们需要设置一个时间,超过该时间lazyLoad必须执行一次,术语叫节流,代码如下

        function throttle(fn , wait, delay) {
            let timeOut = null
            let startTime = new Date()
            let curtTime = null
            return function (){
                curtTime = new Date()
                clearTimeout( timeOut )
                if( curtTime - startTime > delay){
                    fn()
                    startTime = new Date()
                }else {
                    timeOut = setTimeout(()=>{
                        fn()
                        startTime = new Date()
                    }, wait)
                }
            }
        }
      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值