圖片預加載與懶加載

預加載與懶加載,咱們常常常常用到,這些技術不只僅限於圖片加載,咱們今天討論的是圖片加載:
 
1、什麼是圖片預加載與懶加載:
圖片預加載:顧名思義,圖片預加載就是在網頁所有加載以前,提早加載圖片。當用戶須要查看時可直接從本地緩存中渲染,以提供給用戶更好的體驗,減小等待的時間。不然,若是一個頁面的內容過於龐大,沒有使用預加載技術的頁面就會長時間的展示爲一片空白,這樣瀏覽者可能覺得圖片預覽慢而沒興趣瀏覽,把網頁關掉,這時,就須要圖片預加載。固然這種作法實際上犧牲了服務器的性能換取了更好的用戶體驗。
圖片懶加載(緩載):延遲加載圖片或符合某些條件時才加載某些圖片。這樣作的好處是減小沒必要要的訪問數據庫或延遲訪問數據庫的次數,由於每次訪問數據庫都是比較耗時的即只有真正使用該對象的數據時纔會建立。懶加載的主要目的是做爲服務器前端的優化,減小請求數或延遲請求數。
 
2、圖片預加載與懶加載的區別:
二者的行爲是相反的,一個是提早加載,一個是遲緩甚至不加載。懶加載對服務器前端有必定的緩解壓力做用,預載則會增長服務器前端壓力。
 
3、圖片預加載與懶加載實現:
一、實現圖片預加載:
實現預載的方法很是多,能夠用CSS(background)、JS(Image)、HTML(<img />)均可以。經常使用的是new Image();,設置其src來實現預載,再使用onload方法回調預載完成事件。只要瀏覽器把圖片下載到本地,一樣的src就會使用緩存,這是最基本也是最實用的預載方法。當Image下載完圖片頭後,會獲得寬和高,所以能夠在預載前獲得圖片的大小(我所知的方法是用記時器輪循寬高變化)。通常實現預載的工具類,都實現一個Array來存須要預載的URL,而後實現Finish、Error、SizeChange等經常使用事件,能夠由用戶選擇是順序預載或假併發預載。Jquery的PreLoad能夠用於預載。
model:
 

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>img ready</title> </head> <body> <div> <p> <button id="testReadyBtn">開始加載圖片</button> <button id="clsCacheBtn">清空緩存</button> <p>(若是圖片加載事後,瀏覽器會緩存)</p> </p> <div id="status" style="display:none"> <p><strong>imgReady:</strong><p> <p id="statusReady"></p> <p><strong>imgLoad:</strong></p> <p id="statusLoad"><p> </div> <div id="imgWrap"></div> <div style="display:none"></div> </div> </body> <script> var imgReady = function (url, callback, error) { var width, height, intervalId, check, div,img = new Image(), body = document.body; img.src = url; // 從緩存中讀取 if (img.complete) { return callback(img.width, img.height); }; // 經過佔位提早獲取圖片頭部數據 if (body) { div = document.createElement('div'); div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;width:1px;height:1px;overflow:hidden'; div.appendChild(img) body.appendChild(div); width = img.offsetWidth; height = img.offsetHeight; check = function () { if (img.offsetWidth !== width || img.offsetHeight !== height) { clearInterval(intervalId); callback(img.offsetWidth, img.clientHeight); img.onload = null; div.innerHTML = ''; div.parentNode.removeChild(div); }; }; intervalId = setInterval(check, 150); }; // 加載完畢後方式獲取 img.onload = function () { callback(img.width, img.height); img.onload = img.onerror = null; clearInterval(intervalId); body && img.parentNode.removeChild(img); }; // 圖片加載錯誤 img.onerror = function () { error && error(); clearInterval(intervalId); body && img.parentNode.removeChild(img); }; }; </script> <script> /* demo script */ window.onload = function () { var imgUrl = 'http://www.planeart.cn/demo/imgReady/vistas24.jpg?', testReadyBtn = document.getElementById('testReadyBtn'), clsCacheBtn = document.getElementById('clsCacheBtn'), status = document.getElementById('status'), statusReady = document.getElementById('statusReady'), statusLoad = document.getElementById('statusLoad'), imgWrap = document.getElementById('imgWrap'); var imgLoad = function (url, callback) { var img = new Image(); img.src = url; if (img.complete) { callback(img.width, img.height); } else { img.onload = function () { callback(img.width, img.height); img.onload = null; }; }; }; testReadyBtn.onclick = function () { var that = this; that.disabled = true; status.style.display = 'block'; statusLoad.innerHTML = statusReady.innerHTML = 'Loading...'; imgWrap.innerHTML = '<img src="' + imgUrl + '" />'; // 使用佔位方式快速獲取大小 imgReady(imgUrl, function (width, height) { statusReady.innerHTML = 'width:' + width + '; height:' + height; }, function () { statusReady.innerHTML = 'Img Error!'; }); // 使用傳統方式獲取大小 imgLoad(imgUrl, function (width, height) { statusLoad.innerHTML = 'width:' + width + '; height:' + height; that.disabled = false; }, function () { statusLoad.innerHTML = 'Img Error!'; that.disabled = false; }); }; clsCacheBtn.onclick = function () { imgUrl += new Date().getTime(); status.style.display = 'none'; imgWrap.innerHTML = ''; }; }; </script> </html>javascript

二、懶加載實現:
第一種是純粹的延遲加載,使用setTimeOut或setInterval進行加載延遲,若是用戶在加載前就離開了頁面,那麼就不會加載。 
第二種是條件加載,符合某些條件,或觸發了某些事件纔開始異步下載。
 第三種是可視區加載,即僅加載用戶能夠看到的區域,這個主要由監控滾動條來實現,通常會在距用戶看到某圖片前必定距離遍開始加載,這樣能保證用戶拉下時正好能看到圖片。
Jquery的Lazy Load用於圖片緩載
model:

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>原生Js圖片延遲加載</title> <style type="text/css"> *{margin: 0;padding: 0} img.scrollLoading{border: 1px solid #ccc;display:block;margin-top: 10px;} </style> </head> <body> <div id="content"> </div> </body> </html> <script type="text/javascript"> var _CalF = { zsl: function(object) { //選擇器 if (object === undefined) return; var getArr = function(name, tagName, attr) { var tagName = tagName || '*', eles = document.getElementsByTagName(tagName), clas = (typeof document.body.style.maxHeight === "undefined") ? "className": "class"; //ie6 attr = attr || clas, Arr = []; for (var i = 0; i < eles.length; i++) { if (eles[i].getAttribute(attr) == name) { Arr.push(eles[i]); } } return Arr; }; if (object.indexOf('#') === 0) { //#id return document.getElementById(object.substring(1)); } else if (object.indexOf('.') === 0) { //.class return getArr(object.substring(1)); } else if (object.match(/=/g)) { //attr=name return getArr(object.substring(object.search(/=/g) + 1), null, object.substring(0, object.search(/=/g))); } else if (object.match(/./g)) { //tagName.className return getArr(object.split('.')[1], object.split('.')[0]); } }, getPosition: function(obj) { //獲取元素在頁面裏的位置和寬高 var top = 0, left = 0, width = obj.offsetWidth, height = obj.offsetHeight; while (obj.offsetParent) { top += obj.offsetTop; left += obj.offsetLeft; obj = obj.offsetParent; } return { "top": top, "left": left, "width": width, "height": height }; } }; //添加圖片list var _temp = []; for (var i = 1; i < 21; i++) { _temp.push('<img class="scrollLoading" data-src="http://images.cnblogs.com/cnblogs_com/Darren_code/311197/o_' + i + '.jpg" src="https://images0.cnblogs.com/blog/150659/201306/23160223-c81dd9aa9a2a4071a47b0ced2c9118bc.gif" /><br />圖片' + i); } _CalF.zsl("#content").innerHTML = _temp.join(""); function scrollLoad() { this.init.apply(this, arguments); } scrollLoad.prototype = { init: function(className) { var className = "img." + className, imgs = _CalF.zsl(className), that = this; this.imgs = imgs; that.loadImg(); window.onscroll = function() { that.time = setTimeout(function() { that.loadImg(); }, 400); } }, loadImg: function() { var imgs = this.imgs.reverse(), //獲取數組翻轉 len = imgs.length; if (imgs.length === 0) { clearTimeout(this.time); return; } for (var j = len - 1; j >= 0; j--) { //遞減 var img = imgs[j], imgTop = _CalF.getPosition(img).top, imgSrc = img.getAttribute("data-src"), offsetPage = window.pageYOffset ? window.pageYOffset: window.document.documentElement.scrollTop, //滾動條的top值 bodyHeight = document.documentElement.clientHeight; //body的高度 if ((offsetPage + bodyHeight / 2) > (imgTop - bodyHeight / 2)) { img.src = imgSrc; this.imgs.splice(j, 1); } } } } var img1 = new scrollLoad("scrollLoading"); </script> 獲取屏幕的分辨率 <script type="text/javascript"> document.write('您的顯示器分辨率爲:\n' + screen.width + '*' + screen.height + '</br>'); var ww = document.getElementById("con").offsetWidth, w = screen.width/ww, h = screen.height/ww, r = Math.round(Math.sqrt(w*w + h*h) / 2.54); document.write('您的顯示器尺寸爲:\n' + (screen.width/ww).toFixed(1) + '*' + (screen.height/ww).toFixed(1) + ' cm, '+ r +'寸<br/>'); </script>css

 
源引:http://bianhua1314.blog.163.com/blog/static/23894303020147139581721/
相關文章
相關標籤/搜索