天天看點

首屏優化(圖檔懶加載+節流防抖結合)

<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Lazy-Load</title>
  <style>
    .img {
      width: 200px;
      height:280px;
      background-color: gray;
    }
    .pic {
        width: 100%;
        height: 100%;
      
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="img">
      <img class="pic" alt="加載中" src="./images/book1.png">
    </div>
    <div class="img">
      <img class="pic" alt="加載中" src="./images/book2.png">
    </div>
    <div class="img">
      <img class="pic" alt="加載中" src="./images/book3.png">
    </div>
    <div class="img">
      <img class="pic" alt="加載中" src="./images/book4.png">
    </div>
    <div class="img">
      <img class="pic" alt="加載中" src="./images/book5.png">
    </div>
     <div class="img">
      <img class="pic" alt="加載中" src="./images/book6.png">
    </div>
     <div class="img">
      <img class="pic" alt="加載中" src="./images/book7.png">
    </div>
     <div class="img">
      <img class="pic" alt="加載中" src="./images/book8.png">
    </div>
     <div class="img">
      <img class="pic" alt="加載中" src="./images/book9.png">
    </div>
     <div class="img">
      <img class="pic" alt="加載中" src="./images/book10.png">
    </div>
  </div>
  <script>
      window.onload = function(){
         lazyLoad()
      }
     // 擷取所有的圖檔标簽
     const imgs = document.getElementsByTagName('img')
    // 擷取可視區域的高度
    const viewHeight = window.innerHeight || document.documentElement.clientHeight
    // num用于統計目前顯示到了哪一張圖檔,避免每次都從第一張圖檔開始檢查是否露出
    let num = 0
    function lazyLoad(){
        for(let i=num; i<imgs.length; i++) {
            // 用可視區域高度減去元素頂部距離可視區域頂部的高度
            let distance = viewHeight - imgs[i].getBoundingClientRect().top
            // 如果可視區域高度大于等于元素頂部距離可視區域頂部的高度,說明元素露出
            if(distance >= 0 ){
                // 給元素寫入真實的src,展示圖檔
                imgs[i].src = imgs[i].getAttribute('data-src')
                // 前i張圖檔已經加載完畢,下次從第i+1張開始檢查是否露出
                num = i + 1
            }
        }
    }

    // fn是我們需要包裝的事件回調, delay是時間間隔的門檻值
    function throttle(fn, delay) {
        // last為上一次觸發回調的時間, timer是定時器
        let last = 0, timer = null
        // 将throttle處理結果當作函數傳回
        return function () { 
            // 記錄本次觸發回調的時間
            let now = +new Date()
            // 判斷上次觸發的時間和本次觸發的時間差是否小于時間間隔的門檻值
            if (now - last < delay) {
            // 如果時間間隔小于我們設定的時間間隔門檻值,則為本次觸發操作設立一個新的定時器
            clearTimeout(timer)
            timer = setTimeout(function () {
                last = now
                fn()
                }, delay)
            } else {
                // 如果時間間隔超出了我們設定的時間間隔門檻值,那就不等了,無論如何要回報給使用者一次響應
                last = now
                fn()
            }
        }
    }
    //用better_scroll接收throttle傳回的結果
    let better_scroll = throttle(lazyLoad,1000);
     window.addEventListener('scroll', better_scroll, false);
  </script>
</body>
</html>
           

學習于掘金小冊<前端性能優化原理與實踐>

繼續閱讀