摘要: 提到前端性能优化中图片资源的优化,懒加载和预加载就不能不说,下面我用最简洁明了的语言说明懒加载和预加载的核心要点以及实现 懒加载 什么是懒加载 懒加载也就是延迟加载;当访问一个页面时,先将img标签中的src链接设为同一张图片(这样就只需请求一次,俗称占位图),将其真正的图片地址存储在img标签的.
提到前端性能优化中图片资源的优化,懒加载和预加载就不能不说,下面我用最简洁明了的语言说明懒加载和预加载的核心要点以及实现
懒加载
什么是懒加载
懒加载也就是延迟加载;当访问一个页面时,先将img标签中的src链接设为同一张图片(这样就只需请求一次,俗称占位图),将其真正的图片地址存储在img标签的自定义属性中(比如data-src);当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果;这样做能防止页面一次性向服务器响应大量请求导致服务器响应慢页面卡顿或崩溃等问题
为什么要使用懒加载
懒加载对于图片较多页面很长的业务场景很适用,可以减少无效资源的加载
懒加载的实现步骤
1.首先,不要将图片地址放到src属性中,而是放到其它属性(data-src)中
2.页面加载完成后,根据scrollTop判断图片是否在用户的视野内,如果在,则将data-original属性中的值取出存放到src属性中
3.在滚动事件中重复判断图片是否进入视野;如果进入,则将data-original属性中的值取出存放到src属性中
代码实现:
既然懒加载的原理是基于判断元素是否出现在窗口可视范围内,首先我们写一个函数判断元素是否出现在可视范围内:
<script> function isVisible($node){ var winH = $(window).height(), scrollTop = $(window).scrollTop(), offSetTop = $(window).offSet().top; if (offSetTop < winH + scrollTop) { return true; } else { return false; } } </script>
再添加上浏览器的事件监听函数,让浏览器每次滚动就检查元素是否出现在窗口可视范围内:
<script> $(window).on("scroll", function{ if (isVisible($node)){ console.log(true); } }) </script>
现在我们要做的是,让元素只在第一次被检查到时打印true,之后就不再打印了
<script> var hasShowed = false; $(window).on("sroll",function{ if (hasShowed) { return; } else { if (isVisible($node)) { hasShowed = !hasShowed; console.log(true); } } }) </script>
这样我们就实现了懒加载
利用懒加载和AJAX,我们还可以实现无限滚动查看时间线/在滚动页面一段距离后出现回到顶部按钮的效果
懒加载的优点
显著的提高页面加载速度,又不下载多余的资源节省了流量;同时更少的图片并发请求数也可以减轻服务器的压力
懒加载插件
关于图片延时加载,网上有很多应用的例子以及插件;目前研究过的两个插件分别是jquery插件lazyload.js和原生js插件echo.js;二者的区别不用说,jquery插件使用的时候必须引入jquery才可以,且该插件功能强大,灵活性也高;而echo.js是用原生写的插件,代码少,不依赖其他库,拿起来就可以用,但能够实现的效果不如lazyload丰富强大,但基本的延时加载要求都能满足
jquery.lazyload.js
如何使用
延迟加载依赖于于jQuery,第一步引入文件:
<script src ="jQuery.js"></script> <script src="jQuery.lazyload.js"></script>
接下来修改html的一些属性:图像的src地址暂时存储在自定义属性data-original中,然后给需要延时加载图像加上一个特定的类,类的名字由你自己决定,使用的时候统一类名即可;为这些图片绑定延时加载:
<img class="lazy" src="img/grey.gif" data-original="img/example.jpg" width="640" heigh="480">
用的时候就像下面:
$("img.lazy").lazyload();
所有class为lazy的图片将被延迟加载
注意:必须设置图像的尺寸,宽度和高度属性或CSS,否则插件可能无法正常工作
参数设置
1.设置阈值
默认情况下图片在位于可视区域后才开始加载;如果想提前加载图片,可通过设置threshold的值来改变其显示的时间,设置threshold为200使图片在距离屏幕可见区域下方200像素时就开始加载
$("img.lazy").lazyload({ threshold:200 });
2.事件触发加载
默认是scoll事件触发延时加载,即等到用户向下滚动至图片出现在屏幕可视区域时图片才能加载,但可以使用jQueryclick或mouseover等事件触发图片的加载,也可以使用自定义事件,实现只有当用户点击图片图片才能够加载时可以这样写:
$("img.lazy").lazyload({ event : "click" });
注意:你也可以使用这个技巧延迟图片加载,即加载前延迟5秒后再加载图片;就像下面这样(trigger()方法触发被选元素的指定事件类型):
$(function() { $("img.lazy").lazyload({ event:"click" }); }); $(window).bind("load", function() { var timeout = setTimeout(function() { $("img.lazy").trigger("click") //trigger()方法触发被选元素的指定事件类型 }, 5000); });
3.使用特殊效果加载图片
插件默认使用show()方法显示图片;当然你可以使用任何你想用的特效来处理,例如使用fadeIn效果:
$("img.lazy").lazyload({ effect : "fadeIn" //.effect()方法对一个元素应用了一个命名的动画 特效 });
4.为非JavaScript浏览器回退
<img class="lazy" src="img/grey.gif" data-original="img/example.jpg" width="640" heigh="480"> <noscript><img src="img/example.jpg" width="640" heigh="480"></noscript>
可以通过CSS隐藏占位符
.lazy {
display: none;
}
在支持JavaScript的浏览器中必须在DOM ready时将占位符显示出来,这可以在插件初始化的同时完成
$("img.lazy").show().lazyload();
这些都是可选的,但如果你希望插件平稳降级这些都是应该做的
5.图片内容器
可以将插件用在可滚动容器的图片上,例如带滚动条的DIV元素;将容器定义为jQuery对象并作为参数传到初始化方法里面
#container { height: 600px; overflow: scroll; } $("img.lazy").lazyload({ container: $("#container") });
6.当图像并不是连续的
滚动页面时,Lazy Load会循环加载图片;在循环中检测图片是否在可视区域内,默认情况下在找到第一张不在可见区域的图片时停止循环;图片被认为是流式分布的,图片在页面中的次序和HTML代码中次序相同;但是在一些布局中,这样的假设是不成立的;不过你可以通过failurelimit选项来控制加载行为
$("img.lazy").lazyload({ failure_limit : 10 });
将failurelimit设为10令插件找到10个不在可见区域的图片是才停止搜索
7.处理看不见图像
可能在你的页面上有很多隐藏的图片;为了提升性能,Lazy Load默认忽略了隐藏图片;如果想要加载隐藏图片,将skip_invisible设为 false:
$("img.lazy").lazyload({ skip_invisible : false });
echo.js
兼容性:Echo.js使用了HTML5的date属性,并且需要获取该属性的值,所以它并不兼容IE6/IE7
使用方法:
引入文件
<script src="js/echo.min.js"></script>
blank.gif用做默认图片,data-echo的属性值是图片的真实地址,同样最好给图片设置宽度和高度
JavaScript
echo.init({ offset: 0, throttle: 0 });
参数说明
echo.js只有两个参数:offset和throttle
offset:设置图片在离可视区域下方在一定距离后开始被加载
throttle:设置图片延迟多少毫秒后加载
那么上面的代码的意思就是一旦图片进入可视区域就立即加载
怎么样,使用起来真的很简单吧