圖片懶加載

爲何要懶加載

有時候頁面中會有不少圖片,一個圖片就意味着一個http請求,一個js文件幾十k,一張圖片就多是幾M,過多的圖片須要很長的加載時間,等圖片加載完成,早就人走茶涼,圖片懶加載對提高用戶體驗有着顯著的效果瀏覽器

懶加載的原理

當圖片不在可視區域內時,統一設置imgsrc爲指定圖片src='default.png',添加data-src(自定義屬性)屬性指向真實圖片url
bash

<img src='default.png' data-src='httt://www.xxx.com/images/001.jpg'>
複製代碼

監聽scroll事件,當圖片出如今可視區時,提取data-src的值並賦給src,加載真正圖片app

實現代碼

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必須執行一次,術語叫節流,代碼以下ui

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))
複製代碼
相關文章
相關標籤/搜索