图片懒加载

图片懒加载技术

为什么要懒加载

有时候页面中会有很多图片,一个图片就意味着一个http请求,一个js文件几十k,一张图片就可能是几M,过多的图片需要很长的加载时间,等图片加载完成,早就人走茶凉,图片懒加载对提升用户体验有着显著的效果

懒加载的原理

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

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

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

实现代码

        let img = document.getElementsByTagName('img')
        //设置每次遍历的起始图片,防止重复加载
        let n = 0
        //加载可视区域图片
        lazyLoad()
        window.onscroll = lazyLoad
        function lazyLoad() {
            let seeHeight = document.documentElement.clientHeight
            let scrollHeight = document.body.scrollHeight
            for (let i = n; i<img.length;i++) {
               if(img[i].src === 'default.png'){
                   if(img[i].offsetHeight < seeHeight + scrollHeight){
                       img[i].setAttribute('src',img[i].getAttribute('data-src'))
                       n++
                   }
               }
            }
        }
复制代码

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

       let img = document.getElementsByTagName('img')
        //设置每次遍历的起始图片,防止重复加载
        let n = 0
        //加载可视区域图片
        lazyLoad()
        function lazyLoad() {
            let seeHeight = document.documentElement.clientHeight
            let scrollHeight = document.body.scrollHeight
            for (let i = n; i<img.length;i++) {
               if(img[i].src === 'default.png'){
                   if(img[i].offsetHeight < seeHeight + scrollHeight){
                       img[i].setAttribute('src',img[i].getAttribute('data-src'))
                       n++
                   }
               }
            }
        }
        //防抖
        function debounce(fn,wait) {
            let timeout = null
            return function(){ 
                let context = this
                let args = arguments
                clearTimeout(timeout)
                timeout = setTimeout( function(){
                  fn.apply(context,args)
                },wait)                    
            }
        }
        window.addEventListener('scroll',debounce(lazyLoad,800),true)
复制代码

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

       let img = document.getElementsByTagName('img')
        //设置每次遍历的起始图片,防止重复加载
        let n = 0
        //加载可视区域图片
        lazyLoad()
        function lazyLoad() {
            let seeHeight = document.documentElement.clientHeight
            let scrollHeight = document.body.scrollHeight
            for (let i = n; i<img.length;i++) {
               if(img[i].src === 'default.png'){
                   if(img[i].offsetHeight < seeHeight + scrollHeight){
                       img[i].setAttribute('src',img[i].getAttribute('data-src'))
                       n++
                   }
               }
            }
        }
        //节流
        function throttle(fn,wait,mustTime){
            let timeout = null
            let startTime = new Date()
            let curTime
            return function(){
                let context = this
                let args = arguments
                curTime = new Date()
                if( (curTime - startTime) >= mustTime){
                     startTime = curTime
                    fn.apply(context,args) 
                    clearTimeout(timeout)    
                }else{
                    clearTimeout(timeout)
                    timeout = setTimeout( function(){
                        fn.apply(context,args)
                        startTime = new Date()
                    },wait)
                }
            }
        }
        window.addEventListener('scroll',throttle( lazyLoad,2000,3000))
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值