「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
为什么要做图片懒加载(lazyload)?
首先我们先来聊聊为啥要做图片懒加载,首先就是在众多网络资源中图片对网页性能的影响一直是大的。如果每次进入页面就请求所有的图片资源,那么可能等这些图片加载出来用户也早就走了。所以,我们需要懒加载,进入页面的时候,只请求可视区域的图片资源。
我们来简单总结一下:
- 一次性把全部图片都加载完毕会极大的延长网页加载时间,从而影响到用户的体验
- 有的时候用户不需要加载出所以的图片而一次性全部加载。
那么如果实现图片懒加载呢?
图片懒加载实现
项目环境搭建
- 使用
npm来初始化项目
npm init -y
- 安装
vite
npm i vite -D
编写页面骨架
- 首先先写一个简单的页面骨架
<ul id="list"></ul>
- 引入index.js文件
<script src="./index.js"></script>
- 在index.js文件中实现一个简单的图片懒加载
;((document)=>{
const oList = document.querySelector("#list")
const init ()=>{}
init ()
})(document)
- 初始化时,将img的src设置成
default.gif
const oList = document.querySelector("#list")
function createLi(data){
const oLi = document.createElement("li")
oLi.innerHTML = `
<img src="./image/default.gif" data-src="./image/img.jpg" />
`
return oLi
}
const init = ()=>{
for(let i = 0; i<200;i++){
oList.appendChild(createLi(i))
}
}
init = ()
- 从页面获取所有的图片。
let imgs = document.querySelectorAll('img[data-src]')
- 遍历每个图片判断当前图片是否在可视区的范围内。
imgs.forEach((item, index) => {
if (item.dataset.src === '') return
const distance = viewHeight - item.getBoundingClientRect().top;
if (distance>0) {
item.src = item.dataset.src
item.removeAttribute('data-src')
}
})
- 如果到了就设置图片的 src 属性。
imgs.forEach((item, index) => {
if (item.dataset.src === '') return
const distance = viewHeight - item.getBoundingClientRect().top;
})
- 最后记着绑定 window 的
scroll事件,对其进行事件监听。同时在页面加载完毕时也要调影响lazyload方法
window.addEventListener('scroll', lazyload)
这样一个简单的图片懒加载就已经完毕了,但是还是有一个比较大的问题就是scroll事件触发太多了,我们应该使用节流来优化一下。
使用防抖函数优化项目
- 定义一个
debounce函数
function debounce(fn, delay = 500, ...args) {
let timer = null;
// 这里的e是event事件对象
return function (e) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
- 将事件监听
scroll改造一下
window.addEventListener('scroll', debounce(lazyload, 200))