懶加載和預加載

懶加載

懶加載在一些圖片繁多的網站很常見, 舉個簡單的例子, 淘寶的首頁裏有不少商品圖片, 用戶能夠一直往下拉, 可是不少用戶每每都下拉不了多少就跳轉到別的地方了, 假如一次性把首頁的全部圖片都請求加載下來, 這會致使幾個嚴重的問題:
javascript

  1. 影響網頁加載速度
  2. 浪費用戶帶寬
  3. 影響瀏覽器並行加載同域名下的其餘資源 (瀏覽器並行加載同域資源有數量限制)

懶加載的實現原理

將頁面的圖片的 src 設爲 loading 圖片的路徑, 將真實路徑存儲起來, 同時給未加載的圖片添加標記屬性。
監聽頁面的滾動事件(這裏最好作一下節流), 滾動時遍歷未加載的圖片, 獲取圖片距離可視區頂部的高度, 假如小於頁面高度, 就將 src 替換真實的 urlcss

代碼實現

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Lazyload 1</title>
</head>
<body>
  <img src="images/loading.gif" data-src="images/1.png">
  <img src="images/loading.gif" data-src="images/2.png">
  <img src="images/loading.gif" data-src="images/3.png">
  <img src="images/loading.gif" data-src="images/4.png">
  <img src="images/loading.gif" data-src="images/5.png">
  <img src="images/loading.gif" data-src="images/6.png">
  <img src="images/loading.gif" data-src="images/7.png">
  <img src="images/loading.gif" data-src="images/8.png">
  <img src="images/loading.gif" data-src="images/9.png">
  <img src="images/loading.gif" data-src="images/10.png">
  <img src="images/loading.gif" data-src="images/11.png">
  <img src="images/loading.gif" data-src="images/12.png">
  <script>
    class LazyLoad {
      constructor(){
        this.clientHeight = window.innerHeight  // 可視區高度
        this.initLoad()  // 初始加載
        this.bindScrollEvent()
      }
      initLoad(){
        this.lazyLoad()
      }
      bindScrollEvent(){
       let fn = this.throttle(() => {
          this.lazyLoad()
        }, 300)  // 300ms可執行一次 
       document.addEventListener('scroll', fn)
      }
      lazyLoad(){
        let images = document.querySelectorAll("img[data-src]")
        Array.from(images).forEach((img) => {
          let offsetTop = this.getPosition(img)
          if(offsetTop < this.clientHeight){
            img.src = img.getAttribute("data-src")
            img.removeAttribute('data-src', '')  // 每次刪除已加載圖片的 data-src 屬性, 避免下次再遍歷到, 提高性能
          }
        })
      }
      getPosition(el){
        return el.getBoundingClientRect().top
      }
      throttle(fn, timeout){  // 節流
        let perious = 0
        return function(){
        let now = +new Date()
          let args = arguments
          if(now - perious >= timeout){
            perious = now
            fn.apply(this, args)
          }
        }
      }
    }
    let lazyLoadObj = new LazyLoad()
  </script>
</body>
</html>
複製代碼

預加載

預加載與懶加載相反, 懶加載是延遲加載, 在須要展現或用到的時候才加載
預加載是預先加載好後面須要用到的資源, 後面使用的時候直接去緩存裏取。舉個栗子, 好比一個網站的開場動畫, 這些動畫是由不少圖片組成的, 假如不預先加載好, 那就會形成動畫不流暢產生閃動白屏。
html

預加載實現

HTML 實現預加載

在 link 標籤上設置 rel="prefetch" 能夠實現預加載, 該方法兼容性還不太好。java

CSS 實現圖片預加載

將圖片放在 CSS 中加載, 但不顯示跨域

#preload { background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px; }
複製代碼

JS 實現預加載

JS 實現預加載 js 文件和 css 文件時, 標籤必須嵌入頁面纔會生效。瀏覽器

// CSS
var css = document.createElement('link');
css.type = "text/css";
css.rel  = "stylesheet";
css.href = "http://domain.tld/preload.css";
document.body.appendChild(css)

// JS
var js  = document.createElement("script");
js.type = "text/javascript";
js.src  = "http://domain.tld/preload.js";
document.body.appendChild(js)

// img
new Image().src = "http://xxxx.com"
複製代碼

Ajax 實現預加載

Ajax 實現預加載比較好的一個點是, 不須要建立標籤影響到頁面, 可是可能會有跨域問題緩存

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://xxxx.js');
xhr.send('');
複製代碼
相關文章
相關標籤/搜索