当做网页性能优化的时候,对多图片的页面,加载页面的时候用懒加载是一个不二之选,当然可以用缓存到用户端来优化再次请求图片的速度。
懒加载的时候可以在可视化的区域加载图片,等滚到可视区域之后再加载其它的图片。这样对页面加载的性能上有很大的提升,也增加了用户体验。
懒加载如何实现呢,其实原理上很简单,在页面载入的时候将页面上的img标签的src指向一个小图片,
把真实地址存放在一个自定义属性中,这里我用data-src来存放,如下。
<img src="loading.gif" data-src="http://xxx.ooo.com/img/xxx.jpg" />
然后将页面img标签获取并保存,开启一个定时器,遍历保存的img标签,
判断其位置是否出现在了可视区域内。如果出现在可视区域了那么就把真实的src地址给赋值上。
并且从数组中删除,避免重复判断。 那么你可能会问,如何判断是否出现在可视区域内吗?
那就是你可以获取当前img的相对于文档顶的偏移距离减去浏览器窗口高度的距离,
然后和scrollTop在进行比较,如果小于scrollTop则出现在了可视区域内了,
反之,则没有。
下面是懒加载的代码,比较简约。
/*! Echo v1.4.0 | (c) 2013 @toddmotto | MIT license | github.com/toddmotto/echo */ window.Echo = (function (window, document, undefined) { 'use strict'; var store = [], offset, throttle, poll; var _inView = function (el) { var coords = el.getBoundingClientRect(); return ((coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset)); }; var _isDeal = function(el){ return el.getAttribute('src') === el.getAttribute('data-echo'); } var _pollImages = function () { for (var i = store.length; i--;) { var self = store[i]; if (!_isDeal(self) && _inView(self)) { self.src = self.getAttribute('data-echo'); store.splice(i, 1); } } }; var _throttle = function () { clearTimeout(poll); poll = setTimeout(_pollImages, throttle); }; var init = function (obj) { var nodes = document.querySelectorAll('[data-echo]'); var opts = obj || {}; offset = opts.offset || 0; throttle = opts.throttle || 250; for (var i = 0; i < nodes.length; i++) { store.push(nodes[i]); } _throttle(); if (document.addEventListener) { window.addEventListener('scroll', _throttle, false); } else { window.attachEvent('onscroll', _throttle); } }; return { init: init, render: _throttle }; })(window, document);
上述解决了图片懒加载的问题,但在项目中如果总是看到loading的图标怎么看都不爽,既然这样我们就改一下
<div class="lazy"><img src="small.jpg" data-src="big.jpg" /></div>css如下:
.lazy{ background-image:url("loading.gif"); }
这样当页面渲染的时候可以先加载小图,这样loading的图标就不会那么多了。当然这里资源加载的数量变多了,但可以缓存小图片资源。