Web开发编程网
分享Web开发相关技术

图片懒加载

为什么要懒加载

有时候页面中会有很多图片,一个图片就意味着一个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))

作者:Webwwl
链接:https://juejin.im/post/5aa68f226fb9a028dc40ac5d
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

未经允许不得转载:WEB开发编程网 » 图片懒加载
微信扫码关注微信公众号

WEB开发编程网

谢谢支持,我们一直在努力

安全提示:您正在对WEB开发编程网进行赞赏操作,一但支付,不可返还。