网页性能优化之图片懒加载
前言
图片懒加载(Lazy Loading)是一种网页优化技术,旨在提升页面性能和用户体验。通常,当一个网页被加载时,所有的内容,包括图片、视频等媒体文件,都会立即被下载和渲染。这种方式在图片较多或页面较长的情况下会造成初始加载时间过长,用户必须等待所有内容加载完毕才能开始浏览。 懒加载通过推迟图片的加载时间,直到它们即将进入用户的视野范围内才进行加载,从而解决了上述问题。具体而言,当用户向下滚动页面时,只有那些实际可见或接近可见区域的图片才会被下载和显示。这样一来,可以显著减少初始页面加载时间,节省带宽资源,并提高整体的用户体验。
作用具体包括以下几点:
- 加快页面加载速度:通过延迟加载图片,特别是对于大量图片的网页,可以加快页面的初次加载速度。这意味着用户能够更快地看到页面内容,并且不需要等待所有图片都加载完成才能进行交互。
- 减少带宽消耗:在用户浏览网页时,可能并不会滚动到页面底部或者查看所有图片,因此延迟加载图片可以减少不必要的网络请求和带宽消耗。
- 提升用户体验:页面加载速度是用户体验的一个重要因素,快速加载页面能够提升用户满意度并降低跳出率。通过图片懒加载,页面加载速度得以提升,从而改善用户体验。
- 节省服务器资源:延迟加载不必要的图片,可以减轻服务器的负担,节省服务器资源,尤其是在高访问量的网站上表现更为突出。
综合来说,图片懒加载通过延迟加载图片资源,能够有效提升页面加载速度,改善用户体验,减少带宽消耗,并节省服务器资源,是前端性能优化中常用的手段之一。
准备工作
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641293753_img_png">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642423719_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190808/v2_1565254363234_img_jpg">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425030_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425101_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425061_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190904/v2_1567591358070_img_jpg">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567640518658_img_png">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000">
<img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974454_img_000">
我们首先引入若干张图片,将所有图片的要显示实际图片先全部定义成相同的,这里我们放的是占内存非常小的一个图片,在进行加载时几乎不消耗时间。然后用data-src去存储我们最后的实际图片。
body{
background-color: pink;
}
img {
display: block;
margin-bottom: 50px;
width: 400px;
height: 400px;
}
在我们的css代码要干的任务比较简单,我们为了区分,将整个body设置为粉色,然后把图片转换成块级元素进行显示,然后设置元素之间的上下间距,再给一个宽高,用来占据最后我们要显示内容的图片。
懒加载函数
这段代码实现了图片懒加载的功能,通过监听页面滚动事件来动态加载图片,以提高页面加载速度和性能。首先,它获取所有img
标签,并记录图片数量和当前已加载的图片索引。然后,在滚动事件触发时,判断图片是否进入可视区域,若是则将data-src
属性的真实图片路径赋给src
属性,并记录已加载图片的索引。最后,当所有图片都加载完成时,移除滚动事件监听器,以节省资源消耗。
图片懒加载技术能够优化页面加载性能,特别是对于包含大量图片的页面,能够显著减少初次加载的时间和带宽消耗。这种技术的应用可以提升用户体验,特别是在移动设备和网络条件较差的情况下。因此,通过监听页面滚动事件动态加载图片是一种常见的前端优化手段,有助于提高页面的整体性能和响应速度。
const imgList = document.getElementsByTagName('img');
const num = imgList.length;
let n = 0;
function lazyload() {
// 获取可视区域一屏的高度
let screenHeight = document.documentElement.clientHeight;
// console.log(screenHeight);
// 获取滚动条滚动的距离 多浏览器适配
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
console.log(scrollTop);
for (let i = n; i < num; i++) {
if(imgList[i].offsetTop < screenHeight + scrollTop) {
imgList[i].src = imgList[i].getAttribute('data-src');
// 记录已经加载过的图片的下标
n = i + 1;
if(n === num) {
console.log('所有图片加载完成');
window.removeEventListener('scroll', throttleLazyload)
}
}
}
}
我们的懒加载函数首先获取可视区域的高度,然后获取我们滚动的距离,大致思路大家也应该了解,就是当我们的图片距离页面顶部的距离等于可视区域高度加上我们滚动距离时为一个临界,当后者距离超过它时图片就应该显示出来了。这是我们图片懒加载的核心。screenHeight 表示可视区域大小,scrollTop表示滚动距离,我们n值赋初值0,首先判断所有图片的距离,当到达临界点时将图片的实际地址改为真正的图片。我们之所以不直接把for循环i值赋初值0是因为我们还要记录所加载的图片总数,当图片总数等于我们的n时,不需要再次进行图片的加载了,这个时候我们调用window.removeEventListener('scroll', throttleLazyload),目的是移除懒加载函数封装后的节流函数,也就是移除掉这个函数,具体含义我们稍后会讲。
document.addEventListener('DOMContentLoaded', () => {
console.log('DOMContentLoaded');
lazyload();
})
因为我们前面几张图片需要正常显示,因此在系统加载完毕html和css之后我们就需要先把能看见的图片显示。所以这次我们要调用一次这个函数。
到这里,我们的图片懒加载的核心步骤就已经完成啦!
懒加载的节流优化
我们看见上面那段代码时,其实是可以发现我们可以做的更好一点的,首先我们引入一下节流函数的相关概念
function throttle(func, limit) {
//记录当前是否在节流状态
let inThrottle;
//返回一个函数用于作为节流包装后的函数
return function () {
// 保存当前调用的上下文和参数
const context = this;
const args = arguments;
// 如果不在节流状态
if (!inThrottle) {
//调用原函数,并传递当前的上下文和参数
func.apply(context, args);
//将状态设置为节流状态中,阻止下一次的立即执行
inThrottle = true;
//使用定时器在limit时间后重置节流状态,允许下一次执行
setTimeout(() => inThrottle = false, limit);
}
}
}
整个节流函数的流程如下:
-
定义一个变量
inThrottle
用于记录当前是否处于节流状态。 -
返回一个新的包装函数,这个函数在每次调用时:
-
保存当前的执行上下文和参数。
-
检查是否处于节流状态:
- 如果不在节流状态,则立即调用原函数
func
,并设置节流状态为true
。 - 使用
setTimeout
在指定的limit
时间后重置节流状态,使得下一次调用可以执行。
- 如果不在节流状态,则立即调用原函数
-
这种实现方式确保了在定义的时间间隔limit
内,func
最多只能被调用一次,从而有效控制了高频率事件的处理,避免了资源浪费,提高了性能。
大家是否想过,如果我们直接将懒加载函数绑定滚动事件,会不会导致懒加载函数在短时间内被大量触发导致不必要的浪费?举个很明显的例子,如果滚动了100像素,函数会被触发100次,但是还没有滚动到下一个图片,并不需要显示,那么函数100次的触发不就被浪费了嘛?因此我们将这个函数封装成一个节流函数,规定时间内多次触发,只执行一次。
const throttleLazyload = throttle(lazyload, 1000);
window.addEventListener('scroll', throttleLazyload);
这里我们将懒加载函数变成可节流的懒加载函数,然后绑定滚动事件,即使1秒内我们滚动速度再快,里面的函数也只被执行一次,我们这里是为了方便看出节流效果设置为1秒,正常情况肯定没有这么长哦!
滚动到最后一张图片效果如下:
转载自:https://juejin.cn/post/7381333086111744019