前言
本文将探讨懒加载技术如何能有效优化网页加载性能,带来更顺畅的浏览体验。
并且深入了解懒加载的原理,同时给出具体的实现方法。
接下来就让我们一起探索这项革命性的前端技术,掌握提升网页速度的秘密!
实现
html讲解
首先我们准备了一张图片
html
<img src = 'https://img.36krcdn.com/20190905/v2_1567641974410_img_000' />
当这段代码在浏览器时会发生什么?
答案是会立即发起一个对 'https://img.36krcdn.com/20190905/v2_1567641974410_img_000'
这个图片资源的请求,并尝试立即下载和渲染这个图片。
那如果有10张、20张、甚至更多呢?如果都同时去加载,这必然会给浏览器带来巨大的负担!
所以我们不应该一次将所有的图片全部加载,而是当图片到了用户屏幕里面才去加载,这便是懒加载
接下来我来为大家讲解如何去实现懒加载
首先准备11张图片,并将图片的src让他去加载https://misc.360buyimg.com/mtd/pc/common/img/blank.png
,该链接是一个只有一像素的图片,然后为img
添加data-src
数据属性,在data-src
数据属性里面才是真正要去加载的图片,具体代码如下
html
<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">
js讲解
懒加载简单来说就是图片到了可视区域才去加载,那么如何去做判断呢?
- 首先第一步我们肯定是需要拿到所有图片的dom元素的,并判断有多少张图片
js
const imgList = document.getElementsByTagName('img');
const num = imgList.length;
- 第二步编写懒加载的函数
js
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
。 -
然后遍历
imgList
数组中的图片元素。对于每个图片元素:- 检查该图片元素的
offsetTop
是否小于screenHeight + scrollTop
,也就是检查图片是否已经进入可视区域。 - 如果已经进入可视区域,则将图片的
src
属性设置为data-src
属性中存储的图片 URL,从而加载图片。 - 同时记录下已经加载过的图片的下标
n
。 - 如果所有图片都已经加载完成 (
n === num
),则移除窗口的scroll
事件监听器,因为不再需要继续执行懒加载逻辑。
- 检查该图片元素的
- 此时只需要监听鼠标滚轮事件触发懒加载函数即可
js
window.addEventListener('scroll', lazyload)
这个时候其实已经实现滚动鼠标即可加载图片了,但是当我们打开网页时,第一页已经在可视区域的图片并未加载,因为还没有滚动鼠标,所以我们需要提前调用一次图片加载
js
document.addEventListener('DOMContentLoaded', () => {
console.log('DOMContentLoaded');
lazyload()
})
DOMContentLoaded
事件在 HTML 文档完全加载并解析完成后触发,此时 DOM 树已经完全构建好,但是图像、样式表和脚本可能尚未完成加载。
通过将 lazyload()
的调用放在 DOMContentLoaded
事件的回调函数中,可以确保在 DOM 结构完全构建好之后再执行懒加载逻辑。这样可以避免在 DOM 还没有完全加载的情况下就开始执行懒加载,从而导致可能出现的错误,体现了对生命周期的理解
这时候我们就已经实现了懒加载的功能,但是滚动事件频繁触发,我们并不需要如此的频繁,可以采取一个节流的措施,让我们来实现一个简单得节流函数吧
js
function throttle(func, limit) {
let inThrottle;
return function() {
const context = this;
const args = arguments;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
-
throttle
函数接受两个参数:func
: 需要节流执行的函数。limit
: 限制函数执行的时间间隔(单位为毫秒)。
-
throttle
函数返回一个新的函数,这个新函数就是经过节流处理的版本。 -
在新函数的内部:
- 定义一个
inThrottle
变量,用于记录函数是否正在执行。 - 当函数被调用时,先检查
inThrottle
变量是否为true
。 - 如果
inThrottle
为false
,则执行原始函数func
,并将inThrottle
设置为true
。 - 然后使用
setTimeout
设置一个定时器,在limit
毫秒后将inThrottle
重置为false
。
- 定义一个
最后修改scroll事件
js
const throttleLazyload = throttle(lazyload, 200)
window.addEventListener('scroll', throttleLazyload)
最终我们实现了页面的懒加载效果
总结
本文带大家深入学习了结合节流去实现页面的懒加载效果,通过结合节流优化性能,并注意一些细节实现,可以开发出一个优秀的懒加载功能,大幅提升网页的加载性能和用户体验。相信大家在认真学习了本文之后也能自己去做一个懒加载效果了,让我们一起动手coding起来吧!
完整代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>懒加载</title>
<style>
body{
background-color: #000000;
}
img {
display: block;
margin-bottom: 50px;
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<!-- data-src为数据属性 -->
<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">
</script>
<script>
const imgList = document.getElementsByTagName('img');
const num = imgList.length;
// console.log(imgList);
let n = 0;
// 注册在scroll事件中的触发函数
const throttleLazyload = throttle(lazyload, 200)
window.addEventListener('scroll', throttleLazyload)
// DOMContentLoaded html和css页面加载完成时触发,保证第一次页面的图片不用滚轮加载图片
document.addEventListener('DOMContentLoaded', () => {
console.log('DOMContentLoaded');
lazyload()
})
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)
}
}
}
}
function throttle(func, limit) {
let inThrottle;
return function() {
const context = this;
const args = arguments;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
</script>
</body>
</html>