文章目录
什么是懒加载
在一些网站或者app上会看到 鼠标或手势过快,而图片没有加载出来由色块或其他图片代替的情况,当图片出现在我们看到的视图中,再迅速将占位图片换成我们真正想展示的图片,这里使用了一种技术,图片懒加载
为什么要懒加载
当你打开一个网站时,浏览器会做许多工作,这其中包括下载各种可能用到的资源,然后渲染呈现在你面前,假设你的网站有大量的图片,那么加载的过程是很耗时的,尤其像那些新闻资讯类需要大量图片的网站,可想而知,网站的初始加载时间会很长,再加上网络等其它影响,用户体验会很差。我们都希望一输入网址,页面立马就呈现在眼前。
既然想要页面立马呈现在面前,那势必要减少浏览器的负荷,优化代码,减少一些不必要的请求和不必要资源的加载,因为你打开网站的时候,浏览器会把所有可能的资源都下载好,而实际上有些资源你并不需要用到,这就造成了浪费。所以有必要在一些资源上做下优化,提高网站加载速度。
图片懒加载的方法
这里介绍了几种方法,分别是监听 scroll、resize 事件,使用 Intersection Observer API 以及 Chrome70 自带的懒加载设置和jquery.lazyload.min.js 以及 echo.min.js
1、滚动事件监听
前面说到要等图片出现在视口时才加载,那么肯定要监控浏览器的 scroll 事件,并且要计算图片与浏览器窗口的距离来选择替换图片的 src 地址。代码如下:
HTML
// 引入 lodash 库
<script src="https://cdn.bootcss.com/lodash.js/4.17.12-pre/lodash.core.min.js"></script>
<div>
<img class="lazy-load" data-src="https://source.unsplash.com/random/600" alt="">
<img class="lazy-load" data-src="https://source.unsplash.com/random/700" alt="">
<img class="lazy-load" data-src="https://source.unsplash.com/random/800" alt="">
<img class="lazy-load" data-src="https://source.unsplash.com/random/900" alt="">
</div>
CSS
div {
margin-top: 350px;
}
.lazy-load {
width: 200px;
height: 150px;
}
JS
let lazyImages = [...document.querySelectorAll('.lazy-load')]
let inAdvance = 300
function lazyLoad() {
lazyImages.forEach(image => {
if (image.offsetTop < window.innerHeight + window.pageYOffset + inAdvance) {
image.src = image.dataset.src; // 替换真实图片的 URL
}
})
}
lazyLoad();
window.addEventListener('scroll', _.throttle(lazyLoad, 50))
window.addEventListener('resize', _.throttle(lazyLoad, 50))
其中有几个属性,首先是 data-src,它是自定义属性,可以在 js 里通过 dataset 获得它的属性值;还有 offsetTop ,innerHeight 以及 pageYOffset 属性,你可以通过 MDN 文档查询他们的定义和用法;最后是 _.throttle 函数,它是一个节流函数,引用自 lodash 库,因为监听 scroll 滚动以及 resize 窗口改变事件会不断地触发,过于频繁,所以使用节流函数让其每隔一段时间执行,节省开销。
2、Intersection Observer API
Intersection Observer - Web API 接口参考 | MDN 地址: https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver
Intersection observer 接口可以方便我们操作,它可以异步观察目标元素与祖先元素或顶层文件的交集变化。简单的说,以前我们需要自己去写滚动监听事件函数,现在,这个 API 可以帮助我们,我们只需要统一写一个 观察函数 ,每当想观察的元素进入视口,也就是我们看见它时,就执行相应的操作。
看看以下 js 代码:
<style> // css 部分
.lazy-load {
width: 400px;
height: 300px;
}
</style>
<div>
<img class="lazy-load" data-src="https://source.unsplash.com/random/600" alt="">
<img class="lazy-load" data-src="https://source.unsplash.com/random/700" alt="">
<img class="lazy-load" data-src="https://source.unsplash.com/random/800" alt="">
<img class="lazy-load" data-src="https://source.unsplash.com/random/900" alt="">
</div>
js 代码
document.addEventListener("DOMContentLoaded", function() {
let lazyImages = [...document.querySelectorAll('.lazy-load')];
if ("IntersectionObserver" in window) {
// 创建一个观察函数,以便待会调用
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src; // 替换 src URL
lazyImageObserver.unobserve(lazyImage); // 解除观察
}
});
});
// 对所有需要懒加载的图片进行 “暗中观察”
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
}else{
alert('您的浏览器不支持 IntersectionObserver');
}
});
可以看到,里面监听了 DOMContentLoaded 事件,当初始的 HTML 文档被完全加载和解析完成之后,这个事件就被触发,在页面初始之后获取到所有图片元素,然后进行观察。
这么好的API 肯定也有缺点,就是浏览器兼容问题!! !
只有 Chrome 支持的最好,从 58 以上版本就完全支持了,Firefox 也不错。如果你的项目不需要考虑兼容的话,可以尝试使用,看看效果。
3、Chrome 浏览器自带
这个方法厉害了,没有前面两种方法那么复杂,它是 Chrome 自带的原生 lazyload 属性,只需要一个开关。
chrome://flags/#enable-lazy-image-loading
复制它到 Chrome 浏览器的地址栏,然后找到如下选项,将其设置为「Enabled」。
然后在 HTML 标签里开启:
<img src="https://source.unsplash.com/random/600" alt="" lazyload="on">
不需要多余的代码,不需要 JS ,简直强大。
4、jquery.lazyload.min.js
由于使用jquery 一定要先引入 jquery.js
图片格式: 一定要有宽高,和 data-original 属性
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery.lazy/1.7.10/jquery.lazy.min.js"></script>
<img class="lazy" width="600" height="500" data-original="image/1.jpg" alt="" />
<script>
$(function(){
$("img.lazy").lazyload({
event:"click", //将图片加载放进click事件中
effect:"fadeIn", //淡入效果
failure_limit:10, // 将 failurelimit 设为10,令插件找到10个不在可见区域的
// 图片时才停止搜索(也可以根据布局,改变这个参数)
skip_invisible:false // 想要加载隐藏图片,将skip_invisible 设为false
})
})
</script>
5、echo.min.js
Echo 是一个独立的 JavaScript 懒加载图像的工具,快速、体积小(不足1k)和使用 HTML5 的 data- 属性。Echo 支持 IE8+ ,但它不能兼容IE6、IE7.
和 Lazy Load 一样,Echo.js 也是一个用于图像延迟加载 JavaScript。不同的是 Lazy Load 是基于 jQuery 的插件,而 Echo.js 不依赖于 jQuery 或其他 JavaScript 库,可独立使用。并且 Echo.js 非常小巧,压缩后不足 1KB。
同样图片格式: 一定要有宽高,和 data-original 属性
注:blank.gif为预加载的照片,photo.jpg为最后显示的照片
<img class="lazy" width="600" height="500" src="images/blank.gif" data-echo="image/1.jpg" alt="" />
<!-- blank.gif 是一个 1 x 1 的图片,用做默认图片,data-echo 的属性值是图片的真实地址。 -->
<script src="js/echo.js"></script>
<script>
Echo.init({
offset:0, //离可视区域多少像素的图片可以被加载
throttle:1000 //图片延迟多少毫秒加载
})
</script>
jquery.lazyload.min.js 和echo.min.js 二者都是将data-XX 的属性设置为图片路径,在滚动条之后赋值给src属性,以实现懒加载,实现优化