前面做了個招聘頁面,裡面有大量的圖片需要加載。
一開始都是全部寫在頁面中,在測試環境還看不出很慢,一放到正式環境就不對了。
微信浏覽器本來就覺得慢,現在一下子要加載這麼多圖片,一下子就把屏幕弄白了,過了幾十秒後才會完整的出現Loading圖片。
這顯然是無法忍受的,馬上就加了預加載的功能,我只是簡單的使用了一下。
預加載就是通過Image對象,給這個對象添加“src”屬性,並可以將此對象緩存起來,以後再使用。
<img src="blank.png" data-src="img/p2/1.png" class="img1">
我先給img賦個空白圖,然後通過JS來給src賦data-src中的值,預加載的邏輯從網上找到了相關代碼。
function loadImage(url, callback) { var img = new Image(); img.src = url; if (img.complete) { // 如果圖片已經存在於浏覽器緩存,直接調用回調函數 防止IE6不執行onload BUG callback.call(img); return; } img.onload = function () { callback.call(img);//將回調函數的this替換為Image對象 }; };
在GTmetrix網上做了下性能測試,這個網站會提出改進的建議,並會說明這個改進的具體說明。
還配備了YSlow和PageSpeed性能工具。
在Waterfall中有資源加載記錄,加了data-src屬性的圖片會在JS腳本之後再載入,這樣的話就不會影響Loading效果顯示了。
一般懶加載就是當你做滾動到頁面某個位置,然後再顯示當前位置的圖片,這樣做可以減少頁面請求。
參考了兩個比較火的開源庫,jquery_lazyload和layzr.js,兩者的人氣都很足,不過前者是需要引入jQuery庫的,後者不需要。
當頁面過長的時候就會出現滾動條,而當年滾動到下面的時候,上面的頁面就會看不到,下圖中綠色部分就是那隱藏的頁面。
通過計算,可以獲取圖片的兩個距離值,圖中標注了,然後判斷是否在當前可視區域的頂部和底部的范圍內,如果是就加載圖,不是就不加載。
假設滾動條是在body中,那麼當前可視區域的范圍是:
viewTop = window.scrollY || window.pageYOffset; viewBottom = window.innerHeight + viewTop;
而圖片的top和height是:
nodeTop = node.getBoundingClientRect().top + viewTop; nodeBottom = nodeTop + node.offsetHeight;
在上面出現了幾個尺寸的概念。
Window.scrollY 與 Window.pageYOffset意思差不多,指的是滾動條頂部到網頁頂部的距離。
Window.innerHeight 表示該容器中頁面視圖區的高度(減去邊框寬度)。
Element.getBoundingClientRect() 方法返回元素的大小及其相對於視口的位置。
HTMLElement.offsetHeight = height+padding+border。
更多的尺寸屬性可以參考《JavaScript中尺寸、坐標》
最後在給某個容器綁定“scroll”事件,上面的話是給“window”綁定。
參考資料:
Javascript圖片預加載詳解