图片懒加载是一种前端性能优化技术,通过延迟加载不在视窗内的图片,减少页面初始加载时间和带宽消耗。
浏览器渲染过程
-
下载HTML和CSS:浏览器通过HTTP协议下载HTML文档和CSS样式表。
-
建立DOM树和渲染树:
- HTML标签解析成DOM树。
- CSS解析成渲染树。
- DOM树和渲染树结合生成最终页面。
-
线程机制:
- JavaScript是单线程的,而浏览器是多线程的。
- 浏览器会为
img、link和script标签启动新的下载线程。 - 过多的并发线程可能导致阻塞。
性能优化
- 优化重点在于尽快显示首屏内容。
- 图片懒加载技术主要用于延迟加载不在视窗内的图片。
实现步骤
-
手动控制图片加载:
img标签的src属性会立刻触发图片下载,不适用于懒加载。- 使用自定义属性(如
data-src)来存储图片地址。
-
懒加载逻辑:
- 当页面滚动到一定位置时,加载该位置的图片。
- 使用
dataset属性来存储和获取图片地址。 - 监听
scroll事件,在合适的时机加载图片。
-
获取图片标签和数量:
const imgs = document.getElementsByTagName('img'); const num = imgs.length;我们通过
getElementsByTagName方法获取所有的img标签,并存储其数量。 -
首次加载可视区内的图片:
document.addEventListener('DOMContentLoaded', () => { loadImage(); });当DOM内容加载完成时,立即调用
loadImage函数来加载可视区内的图片。 -
加载图片的函数:
javascript 复制代码 function loadImage() { console.log('hahaha'); let screenHeight = document.documentElement.clientHeight; let scrollTop = document.documentElement.scrollTop || document.body.scrollTop; for (let i = 0; i < num; i++) { if (imgs[i].offsetTop < screenHeight + scrollTop) { setTimeout(() => { imgs[i].src = imgs[i].dataset.src; let n = i + 1; if (n === num) { console.log("所有图片加载完毕"); window.removeEventListener('scroll', throttleLayLoad); } }, 1000); } } }- 获取视窗高度和滚动条的偏移量。
- 遍历所有图片,如果图片的顶部位置在视窗内,则设置其
src属性为data-src的值。 - 使用
setTimeout模拟延迟加载。 - 检查是否所有图片加载完毕,如果是,则移除滚动事件监听器。
-
使用节流技术优化滚动事件:
const throttleLayLoad = _.throttle(loadImage, 500); window.addEventListener('scroll', throttleLayLoad);- 使用Lodash的
throttle函数将loadImage函数进行节流,确保在滚动时每隔500ms最多执行一次。 - 添加滚动事件监听器,调用节流后的
loadImage函数。
- 使用Lodash的
优化建议
-
去掉不必要的
setTimeout:- 当前代码中使用
setTimeout延迟1秒加载图片,这是模拟网络延迟的做法,在实际应用中可能不需要。
- 当前代码中使用
-
检查图片是否已经加载:
- 添加一个检查,避免重复加载已经加载的图片。
修改后的代码如下:
<script>
// 获取所有img标签
const imgs = document.getElementsByTagName('img');
const num = imgs.length;
// 当首次进入页面时,需要加载当前屏幕的图片
document.addEventListener('DOMContentLoaded', () => {
loadImage();
});
// 加载图片的函数
function loadImage() {
let screenHeight = document.documentElement.clientHeight;
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
for (let i = 0; i < num; i++) {
if (imgs[i].offsetTop < screenHeight + scrollTop && !imgs[i].src) {
imgs[i].src = imgs[i].dataset.src;
let n = i + 1;
if (n === num) {
console.log("所有图片加载完毕");
window.removeEventListener('scroll', throttleLayLoad);
}
}
}
}
// 使用lodash的throttle函数来节流,减少滚动事件处理的频率
const throttleLayLoad = _.throttle(loadImage, 500);
// 监听滚动事件
window.addEventListener('scroll', throttleLayLoad);
</script>
通过这些讲解和优化,你应该对懒加载的实现有了更深入的理解。