懒加载原理分析
最近添加了相册功能到网站上,一旦打开浏览器就会加载大量图片,从而造成页面的卡顿和跳动,同时对服务器也造成一定的压力。所以很显然需要用到懒加载功能。
懒加载的概念,就是等到让图片出现在浏览器中的窗口的时候再去加载该图片资源。这样避免网页在同一时间加载过多资源出现的页面卡死。
牛刀小试
现有插件很多,我也直接拿来用了,推荐使用 jQuery 的 lazyload.js ,大致阐述一下它的用法。
<!-- css -->
<style>
img.lazy { /* 设置宽高 */ }
</style>
<!-- html -->
<div>
<img class="lazy" src="1px*1px的图片" data-original="要加载的图片" />
<img class="lazy" src="1px*1px的图片" data-original="要加载的图片" />
<img class="lazy" src="1px*1px的图片" data-original="要加载的图片" />
<img class="lazy" src="1px*1px的图片" data-original="要加载的图片" />
</div>
<!-- js -->
<script src="//apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="//apps.bdimg.com/libs/jquery-lazyload/1.9.5/jquery.lazyload.js"></script>
<script>
$('img.lazy').lazyload({
// 可设置加载时的动画等属性
effect: 'fadeIn'
});
</script>
引入这个插件后短短两三行代码就能启用页面上所有 class 为 lazy 的 img 标签进行懒加载了,同时可配置加载效果。加载时会把 data-original 的资源替换掉 src 的 资源,为了避免页面跳动和更好的用户体验,一般会设置一个默认的 1px × 1px 的图片 (若服务器压力大则可不设置) 并且给Img设置高度。就以上代码而言,对开发者还是非常透明的。
原理剖析
从上面的代码看,可得当加载该图片时,src 会读取 data-original 的数据,这只是该插件的一个规定,在后面我们可以取任何的 data- 作为加载资源。
懒加载的关键还是判断图片何时开始加载,本质就是图片何时'露头' ,来看看浏览器与整个页面的位置关系图。
以从上往下滑动的来加载为例(左右滑动同理)。判断它是否已经加载到滑到了浏览器的视区可以通过三个高度决定。
视窗上方高度
: document.body.scrollTop
视窗高度
: window.innerHeight
图片相对于文档的高度
: 图片DOM.offsetTop
由于 scrollTop 是个变值,所以需要监听它的数值变化,简单整理后如下:
<!-- html -->
<body>
<div style="width:100%;height:900px;"></div>
<div style="width:100%;height:300px;margin-top:50px;padding-top:50px">
<img id="lazy" src="" data-src="资源路径" />
</div>
</body>
<!-- js -->
<script>
window.onmousewheel = function() {
// 可设置 xWill 确定图片在离视区多少高度时就加载
var lazyPic = document.getElementById('lazy');
if (lazyPic.offsetTop <= (window.innerHeight + document.body.scrollTop + xWill)) {
lazyPic.setAttribute('src', lazyPic.getAttribute('data-src'));
}
};
</script>
这样就实现了一个简单的懒加载功能。
总结
对页面上元素的宽高和相对距离有一定认识后,基本的懒加载实现起来其实也很简单,从而解决了资源加载和用户体验上的一些痛点。